使用WinDbg可以查看正在运行的进程中未释放的内存。
-
下载和安装Debugging Tools for Windows。可以从Microsoft官网下载,选择与目标系统版本相匹配的版本。
-
打开WinDbg,并将其附加到目标进程。可以使用“File”菜单中的“Attach to a Process”选项或键入命令“.attach <PID>” (<PID>为目标进程的进程ID)来实现。
-
在WinDbg中加载SOS插件。可以通过键入命令“.load sos.dll”来加载。
-
运行命令“!dumpheap -stat”来显示当前堆中每种对象类型的数量,以及总体使用情况。可以根据对象类型的内存占用量对其进行排序,并检查是否有任何对象类型的使用量异常高。
-
运行命令“!dumpheap -type <Type>” 来列出指定类型的所有实例。可以确定指定类型的所有实例数量,是否存在被无视的内存泄漏。
-
运行命令“!gcroot <Address>” 来查找特定对象的所有GC Roots。这可以帮助您确定保持该对象在内存中所需的对象链(一旦找到,则可以修复缺失信息并释放对象),也可以帮助您确认某个对象是否可以被安全回收。
需要强调的是,在查看和理解WinDbg和SOS提供的数据时,要确保对.NET框架和CLR运行时内部机制有足够的了解。特别是,在排除内存泄漏问题时,应确定哪些对象是需要显式释放的,以及何时释放它们才是最恰当的。
-
在 WinDbg 命令行中输入“!address -summary”,可以查看进程的内存使用情况,包括私有内存、映像内存、共享内存和堆内存等。
-
如果需要进一步分析某个内存地址的使用情况,可以在 WinDbg 命令行中输入“!address [address]”,其中 [address] 是需要分析的内存地址,可以查看该内存地址所属的模块、权限、保护等信息。
-
如果需要查看某个模块的内存使用情况,可以在 WinDbg 命令行中输入“lm vm [module]”,其中 [module] 是需要分析的模块名,可以查看该模块的基地址、大小、代码段、数据段等信息。
使用Windbg分析内存泄漏的步骤如下:
-
打开Windbg并加载需要分析的程序,例如某个进程。
-
使用命令 "!heap -s" 查看堆的统计信息,如:总大小、使用情况等。
-
使用命令 "!heap -stat" 列出所有内存块和其占用的空间。
-
使用命令 "!heap -flt s 2000" 列出大小大于2000字节的资源,并使用 ".logopen <filename>" 命令打开一个日志文件进行记录。
-
让程序运行一段时间,然后使用命令 ".logclose" 关闭日志记录,并使用命令 "!heap -stat -h <heap_address>" 查看特定堆句柄的统计信息。(同样可以使用 !heap -flt s <size> 指定内存大小)
!syncblk 查看进程锁
列表里的 Recursion 代码 (数值-1) /2个线程正在等待一个锁 持有的线程未退出.或者退出慢
!clrstack 找线程
!eeheap -gc
GC Allocated Heap Size: Size: 0xf6bcd838 (4139571256) bytes. GC Committed Heap Size: Size: 0x127188000 (4950884352) bytes. 分配了4.1G 提交了4.9G 差值是缓冲区 . 缓冲区大说明程序有快进快出现象. 为了下次不在向操作系统申请内存. Allocated(当前对象分配的最后位置)和Committed如果相差过大属于快进快出现象.
!eeversion 6.0.1423.7309 free 6,0,1423,7309 @Commit: 2a90daa2cc41ae8f11a2c1519cb8b235f609251a 查看.net 版本 .net 6.0.14
!heapstat -iu