一、简介
今天是《Net 高级调试》的第十一篇文章,这篇文章来的有点晚,因为,最近比较忙,就没时间写文章了。现在终于有点时间,继续开始我们这个系列。这篇文章我们主要介绍托管堆的架构,对象的分配机制,我们如何查找在托管堆上的对象,我学完这章,很多以前很模糊的概念,现在很清晰了,知道了对象代的分配,大对象堆和小对象堆的结构,了解了对象的生命周期,这些是 Net 框架的底层,了解更深,对于我们调试更有利。当然了,第一次看视频或者看书,是很迷糊的,不知道如何操作,还是那句老话,一遍不行,那就再来一遍,还不行,那就再来一遍,俗话说的好,书读千遍,其意自现。
如果在没有说明的情况下,所有代码的测试环境都是 Net Framewok 4.8,但是,有时候为了查看源码,可能需要使用 Net Core 的项目,我会在项目章节里进行说明。好了,废话不多说,开始我们今天的调试工作。
调试环境我需要进行说明,以防大家不清楚,具体情况我已经罗列出来。 操作系统:Windows Professional 10 调试工具:Windbg Preview(可以去Microsoft Store 去下载) 开发工具:Visual Studio 2022 Net 版本:Net Framework 4.8 CoreCLR源码:源码下载
二、基础知识
1、托管堆和垃圾回收 1、Windows 内存架构
要了解 C# 的内存分配机制,首先需要了解 Windows 内存分配的机制,毕竟 CLR 中的内存是从 Windows 上分配过来的。架构图如下:
2 <strong>Number of GC Heaps: 1(只有一个托管堆,就是工作站模式)</strong>
3 generation 0 starts at 0x02f11018
4 generation 1 starts at 0x02f1100c
5 generation 2 starts at 0x02f11000
6 ephemeral segment allocation context: none
7 segment begin allocated size
8 02f10000 02f11000 02f1871c 0x771c(30492)
9 Large object heap starts at 0x03f11000
10 segment begin allocated size
11 03f10000 03f11000 03f2a180 0x19180(102784)
12 Total Size: Size: 0x2089c (133276) bytes.
13 ------------------------------
14 GC Heap Size: Size: 0x2089c (133276) bytes.
复制代码
2.5、查看 Asp.Net Web API 的 GC 模式
调试源码:Example_11_1_2
这里测试的源码时 Web API 项目,直接运行程序,然后我们通过 Windbg 的【attach to Process】命令来查看。附加进程的进程是【iisexpress】,效果如图:
如果你使用的是【Debug】运行的 WEBAPI,调试会失败,附加进程有误,如图:
在 Windbg中提示的具体错误:"The process that you are attempting to attach to is already being debugged. Only one debugger can be invasively attached to a process at a time. A non-invasive attach is still possible when another debugger is attached." ,意思就是:尝试附加到的进程已在调试中。一次只能将一个调试器侵入性附加到进程。把程序的运行模式改为【Release】模式,不用使用调试模式,快捷键:Ctrl+F5,就可以附加进程成功了。
我们可以使用【!eeheap -gc】命令查看一下服务器GC模式。