c#-调查内存泄漏-承诺内存增长-堆很好

我正在调查C#/ WPF / .NET 4.51应用程序中可能的内存泄漏.

启动后以及分配的内存超过顶部数小时后,我直接为应用程序制作了快照.

我使用VisualStudio的进程转储工具检查了托管堆实例.一切看起来都很好.

在WinDbg中打开转储似乎可以确认这一点,因为堆和堆栈以我期望的方式增长(50MB)(左:第一个转储,右:最后一个转储):
c#-调查内存泄漏-承诺内存增长-堆很好

令我烦恼的是,提交的页面的大小增长了很多(左:第一个转储,右:最后一个转储):
c#-调查内存泄漏-承诺内存增长-堆很好

同样,VMMap将这个巨大的提交块显示为“私有数据”(与上面的转储无关.屏幕截图大约在一小时后拍摄):
c#-调查内存泄漏-承诺内存增长-堆很好

请纠正我:
由于堆很好并且使用VirtualAlloc()直接分配了专用字节,因此我可以从可能的泄漏候选列表中排除“我们的”托管应用程序代码.

有没有办法缩小泄漏的原因?

解决方法:

Because of the fact that the heap is fine and the private bytes are directly allocated with VirtualAlloc() I can exclude ‘our’ managed application code from the list of possible leak candidates.

您会看到< unknown>增加了1.5 GB,这是通过VirtualAlloc()分配的内存.这可以是MSXML的内存,该函数或具有自己的堆管理器(因此不属于C堆的Heap类别)的.NET的任何直接(“本机”)调用.

由于您具有.NET应用程序,因此可能是.NET代码造成了1.5 GB的丢失内存.

如果只有转储,则可以使用.loadby sos clr加载,并使用!dumpheap -stat查看内存的位置.输出将列出每个类的对象数和总大小.

从.NET的角度来看,该内存可能已被释放,因此将其列为“空闲”.您可能还需要确保已发生垃圾回收,否则可能会有误报.

故障转储仅向您显示特定时间点的内存.使用专用内存泄漏工具分析此问题的各种方法的好处是,它们将跟踪分配的堆栈跟踪,并更好地了解随时间推移发生的情况.

上一篇:关于WinDbg/SOS如何快速转储堆上所有的.NET异常


下一篇:静态对象是固定的,不能由GC重新分配?