在Gen2中存在大量对象时,使用WinDbg查找内存泄漏

时间:2012-01-10 18:42:35

标签: c# .net debugging memory-leaks windbg

我的.NET应用程序中存在内存问题,在初始化和加载所有内容后,我的应用程序开始在Gen2堆中消耗大约1GB的内存。它随着时间的推移(4-5小时)慢慢消耗Gen2堆中的4GB。我已经使用WinDbg来分析我看到的一些对象类型(以及相关的内存使用情况)正在增加的事情。

实例中增长的所有对象(和mem用法)都由相同的父对象类型引用。此父对象类型有大约3900个实例 - 这永远不会更改。不知何故,我正在将子对象添加到这些父实例的某些中,但我没有很好的方法来查看要添加到哪个3900实例中。

!DumpHeap -mt会显示我所有的父类型,但大小都是一样的,因为它不计算孩子。

!ObjSize也将计算子项的大小,但一次只能获取一个对象(或所有类型的所有对象 - 不仅仅是我的父类型 - 这是太多的对象)

查看子对象并将它们追溯到父对象是没有用的,因为有几百万种这样的类型,我没有办法做某种聚合跟踪。

像CLRProfiler和ANTS这样的工具会使我的应用程序放慢太多(ANTS不那么频繁),以便在任何合理的时间内解决问题。

我尝试使用通常运行的一小部分数据来运行我的应用程序,以便使调试更容易,但我不会在这里遇到内存问题。我认为在我的整个数据集中存在一些引起奇怪事情的边缘情况,但我不知道这些边缘情况是什么,以便将它们隔离成我的整个数据集的子集。

对此有广泛的阅读,并且看不到有人建议在Gen2中有多少物体应该在那里做什么以及少量相同类型的物体不断增加。

任何提示都会非常感激。

3 个答案:

答案 0 :(得分:1)

有趣的谜题。如你所知,当对象幸存下来时,它们会被提升为gen2,因为它们被长期存在的东西所引用。你没有说这是什么样的应用程序 - asp.net,WPF,winforms等等所以我们必须做出一些猜测。

您可以尝试的一种策略是记录。你说有3900个“父对象”实例,有些东西被添加到 - 你可以在接受新对象的父对象上检测方法吗?也许通过记录这些新增内容,您可以了解它们的来源。

答案 1 :(得分:1)

我假设您正在使用SOS。更好的选择是使用PSSCOR2PSSCOR4(取决于您所使用的运行时版本)。 PSSCOR版本!dumpheap有一个额外的delta列,可以帮助您检测哪些实例随时间增长。

答案 2 :(得分:0)

您可以在父类型的所有对象上使用!objsize

.foreach (address {!dumpheap -short -type MyParentType}) {!objsize ${address}}

或方法表,如果您的班级名称不够独特

 !name2ee MyModule MyParentType ; *** to get the method table
 .foreach (address {!dumpheap -short -mt <methodtable>}) {!objsize ${address}}