我正在调查C#/ WPF / .NET 4.51应用程序中可能存在的内存泄漏。
我在启动后直接拍摄了应用程序的快照,并且在分配的内存增加到最顶层几个小时之后。
我使用VisualStudio的进程转储工具检查了托管堆实例。一切看起来都很好。
在WinDbg中打开转储似乎证实了这一点,因为堆和堆栈正以我预期的方式增长(+ 50MB)(左:第一次转储,右转:最后转储):
令我恼火的是,提交页面的大小增长了很多(左:第一次转储,右转:最后转储):
此外,VMMap将这个巨大的提交块显示为私有数据' (与上面的转储无关。截图大约一小时后拍摄):
请纠正我:
由于堆很好并且私有字节直接用VirtualAlloc()分配,我可以排除'我们的'从可能的泄密候选者列表中管理应用程序代码。
有没有办法缩小泄漏的原因?
答案 0 :(得分:2)
由于堆很好并且私有字节直接用VirtualAlloc()分配,我可以从可能的泄漏候选列表中排除'我们的'托管应用程序代码。
您在<unknown>
中看到增加了1.5 GB,这是通过VirtualAlloc()
分配的内存。这可以是MSXML的内存,函数或.NET的任何直接(“本机”)调用,它具有自己的堆管理器(因此不属于Heap
类别,即C ++堆。) / p>
由于你有一个.NET应用程序,它可能是.NET代码,负责1.5 GB的内存丢失。
如果您只有转储,则可以使用.loadby sos clr
加载sos并使用!dumpheap -stat
查看内存的位置。输出将列出对象的数量和每个类的总大小。
内存可能已从.NET的角度释放,因此它被列为Free
。您可能还希望确保垃圾收集已经发生,否则可能存在误报。
崩溃转储仅显示某个特定时间点的内存。使用专门的内存泄漏工具分析这种方法的各种方法的好处是,它们将跟踪分配的堆栈跟踪,并更好地了解随时间发生的情况。
答案 1 :(得分:1)
我们在工作时遇到过类似的问题,我们使用名为dotMemory的JetBrains Memory Profiler解决了这个问题,它向您展示了内存泄漏的确切位置。
我相信他们有30天的试用时间。
答案 2 :(得分:0)