如何在不强制触发GC收集的情况下获取.NET进程内存快照
dotMemory 禁用快照前GC的配置方案
dotMemory CLI 本身支持关闭快照采集前的强制GC逻辑,只需在调用get-snapshot接口时新增preventGc: true参数即可:
##dotMemory["get-snapshot", {pid:12345, preventGc: true}]
如果是通过命令行启动attach到目标进程的场景,也可以在启动时附加全局参数--prevent-full-gc-on-snapshot,所有后续快照采集都不会主动触发GC。
采集到的快照会包含当前堆中所有对象(包含尚未被回收的死对象),分析时可通过dotMemory内置的「仅存活对象」过滤筛除无效对象,不影响内存泄漏的定位效率。
替代内存分析工具
如果需要更低侵入性的采集方案,可选择以下工具:
- PerfView:微软官方推出的.NET 诊断工具,默认采集堆快照时不会主动触发Full GC,生产环境采集开销极低,支持直接分析对象大小、引用链、泄漏点,适配.NET Framework 4.5全版本。操作路径为
Collect > Take Heap Snapshot,选择目标进程即可生成快照。 - procdump + WinDbg/VS 组合:适合无法在生产环境安装GUI工具的场景,先用微软官方的procdump工具捕获进程完整内存转储,命令为
procdump -ma <目标PID> high_mem_dump.dmp,该操作完全不会触发GC,捕获的转储文件拉回本地后,可用WinDbg、Visual Studio、dotMemory任意工具加载分析。 - Visual Studio 诊断工具:如果允许远程调试,可直接通过VS attach到目标进程,在内存峰值阶段采集堆快照,默认也支持关闭预GC逻辑,操作更直观。
生产环境采集注意事项
- 尽量选择业务低峰期执行采集操作,所有内存采集操作都会产生短暂的CPU、磁盘IO开销,避免影响正常业务请求。
- 如果怀疑内存过高由非托管内存泄漏导致,必须采集完整进程转储(procdump加
-ma参数),普通堆快照无法覆盖非托管内存数据。 - 禁用GC后采集的dotMemory快照体积会大于常规快照,需提前预留足够的磁盘存储空间。
内容的提问来源于stack exchange,提问作者TheDoomDestroyer
相关产品推荐
相关产品推荐

