故事:
我们在 .NET 2.0 应用程序中面临非托管内存泄漏。启动后的进程消耗大约 150MB(其中大部分是 .NET 托管、对象状态等)。运行大约 12 小时后,进程消耗了 800MB,接下来的 12 小时后,进程有大约 1.8GB 的 RAM。我刚刚尝试了 JetBrains .NET Memory Profiler、ANTS、.NET Memory Profiler(以及市场上可能有的 2 个下一个 mem 配置文件),这些都没有帮助我,因为我后来检测到我们的进程在未管理的非托管区域中消耗了那么多内存。为了检测到这一点,我使用了带计数器的 Perf 监视器:私有字节(进程)和所有堆中的#字节(.NET CLR 内存),其中私有字节消耗进程分配的所有内存的大约 90%。这就是我切换到非托管调试的原因。
DebugDiag:所以我在进程上运行 debugdiag 并获得完整转储,这是它的快照:
mscorwks.dll(一个已知的 Windows 内存管理器)负责 781,73 MB 的未完成分配。这些分配似乎源自以下模块和功能:
ntdll.dll(一个已知的 Windows 内存管理器)负责 98,24 MB 的未完成分配。这些分配似乎源自以下模块和功能:
按分配计数排名前 4 位的函数
- mscorwks!EEHeapAlloc+15b -- 80 957 个分配
- mscorwks!CLRMapViewOfFileEx+4a -- 4 171 个分配
按分配大小排列的前 4 个函数
- mscorwks!EEVirtualAlloc+15b -- 117,50 MB
- mscorwks!EEHeapAlloc+15b -- 15,03 MB
发现有趣的日志:
功能详情
Function mscorwks!EEVirtualAlloc+15b
- 分配类型 虚拟内存分配
- 分配计数 1471 个分配
- 分配大小 117,50 MB
- 泄漏概率 73%
Function mscorwks!EEHeapAlloc+15b
- 分配类型 堆分配
- 分配计数 80957 个分配
- 分配大小 15,03 MB
- 泄漏概率 72%
Function mscorwks!CExecutionEngine::CheckThreadState+fe
- 分配类型 堆分配
- 堆句柄 0x00000000`00000000
- 分配计数 2 个分配
- 分配大小 304 字节
- 泄漏概率 98%
Function mscorwks!CLRMapViewOfFileEx+4a
- 分配类型 虚拟内存分配
- 分配计数 4171 个分配
- 分配大小 0 字节
- 泄漏概率 73%
我希望有人把我推向正确的方向我怎么能从这个转储中找到内存泄漏?我能够将转储加载到 windbg 并运行标准的 windbg 命令集,但我不知道哪个是能够隔离泄漏的正确命令。
如果有人想提供帮助,我可以提供完整的转储。