C# 内存转储分析方法 C#如何使用WinDbg分析dump文件

来源:这里教程网 时间:2026-02-21 17:40:35 作者:

WinDbg 装什么版本才能分析 C# dump

必须用

WinDbg Preview
(Microsoft Store 版)或
WinDbg 10
(Windows SDK 自带),旧版
WinDbg Legacy
对 .NET Core/.NET 5+ 支持极差,连
clrstack
都可能报
Failed to load data access DLL

关键点:

.NET Framework 程序可用
WinDbg Legacy
+
SOS.dll
(路径需匹配运行时版本,如
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll
.NET Core 3.1+ / .NET 5+ 必须用
WinDbg Preview
,它内置
dotnet-sos
和自动扩展加载能力
32 位 dump 必须用 32 位 WinDbg,64 位 dump 必须用 64 位 WinDbg——混用直接卡在
.loadby sos coreclr
失败

怎么让 WinDbg 正确加载 SOS / DAC 扩展

不是所有 dump 都能直接敲

!clrstack
。常见失败原因是 DAC(Data Access Component)没找到,尤其 .NET Core 程序的 dump 缺少运行时符号或未部署
dotnet-sos

实操步骤:

先执行
.symfix; .reload
确保符号路径正确(默认走 Microsoft 服务器)
对 .NET Core/.NET 5+:运行
dotnet-sos install
(需已装 .NET SDK),然后在 WinDbg 中执行
.load C:\Users\XXX\.dotnet\sos\sos.dll
对 .NET Framework:用
.loadby sos clr
(托管进程)或
.loadby sos mscorwks
(.NET 2.0)
验证是否成功:
!eeversion
应输出运行时版本;
!dumpheap -stat
不报错即 OK

快速定位 C# 崩溃/高 CPU/内存泄漏的命令组合

别一上来就

!dumpheap -stat
——容易卡死或返回无意义数据。按问题类型选命令链:

崩溃(AccessViolation / AV)
!analyze -v
→ 看
FAULTING_IP
STACK_TEXT
→ 再用
!u <code>地址
反汇编托管方法(需 PDB 在符号路径中)
高 CPU
~*e !clrstack
查所有线程托管栈 → 找重复出现的调用栈(比如都在
System.Threading.WaitHandle.WaitOne
或死循环里)
内存泄漏
!dumpheap -stat
看大头类型 → 记下类型名(如
MyApp.CacheItem
)→
!dumpheap -type MyApp.CacheItem
→ 拿几个对象地址 →
!gcroot <code>地址
查谁在引用它

注意:

!gcroot
输出里如果出现
Finalizer Queue
HandleTable
,大概率是未释放的
IDisposable
或事件订阅泄漏。

为什么 !dumpobj 显示字段全是 0x0 或乱码

这不是 WinDbg 问题,是 dump 缺少调试信息或对象已被 GC 回收但内存未覆写。常见于:

Release 编译且未生成 PDB,或 PDB 路径不对 →
.sympath+ C:\path\to\pdbs
+
.reload /f
对象在 Gen 0,而 dump 是
MiniDumpWithHeap
类型(不包含完整堆)→ 必须用
Full Dump
(任务管理器右键 → “创建转储文件”,或
procdump -ma
字段是
string
或引用类型,但
!dumpobj
只显示引用地址 → 需再对地址执行一次
!dumpobj
,或用
!do
(简写)

真正难的是跨 AppDomain 或跨上下文的对象引用链,这时候

!gcroot
可能只显示
DOMAIN(000001234567890)
,得结合源码确认生命周期管理逻辑。

相关推荐

热文推荐