我的.NET应用程序中存在内存问题,在初始化和加载所有内容后,我的应用程序开始在Gen2堆中消耗大约1GB的内存。它随着时间的推移(4-5小时)慢慢消耗Gen2堆中的4GB。我已经使用WinDbg来分析我看到的一些对象类型(以及相关的内存使用情况)正在增加的事情。
实例中增长的所有对象(和mem用法)都由相同的父对象类型引用。此父对象类型有大约3900个实例 - 这永远不会更改。不知何故,我正在将子对象添加到这些父实例的某些中,但我没有很好的方法来查看要添加到哪个3900实例中。
!DumpHeap -mt会显示我所有的父类型,但大小都是一样的,因为它不计算孩子。
!ObjSize也将计算子项的大小,但一次只能获取一个对象(或所有类型的所有对象 - 不仅仅是我的父类型 - 这是太多的对象)
查看子对象并将它们追溯到父对象是没有用的,因为有几百万种这样的类型,我没有办法做某种聚合跟踪。
像CLRProfiler和ANTS这样的工具会使我的应用程序放慢太多(ANTS不那么频繁),以便在任何合理的时间内解决问题。
我尝试使用通常运行的一小部分数据来运行我的应用程序,以便使调试更容易,但我不会在这里遇到内存问题。我认为在我的整个数据集中存在一些引起奇怪事情的边缘情况,但我不知道这些边缘情况是什么,以便将它们隔离成我的整个数据集的子集。
对此有广泛的阅读,并且看不到有人建议在Gen2中有多少物体应该在那里做什么以及少量相同类型的物体不断增加。
任何提示都会非常感激。
答案 0 :(得分:1)
有趣的谜题。如你所知,当对象幸存下来时,它们会被提升为gen2,因为它们被长期存在的东西所引用。你没有说这是什么样的应用程序 - asp.net,WPF,winforms等等所以我们必须做出一些猜测。
您可以尝试的一种策略是记录。你说有3900个“父对象”实例,有些东西被添加到 - 你可以在接受新对象的父对象上检测方法吗?也许通过记录这些新增内容,您可以了解它们的来源。
答案 1 :(得分:1)
答案 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}}