简体   繁体   English

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

[英]Find memory leaks with WinDbg when lots of objects are present in Gen2

I've got a memory problem in my .NET application where my app starts off consuming about 1GB in the Gen2 heap after everything is initialized and loaded. 我的.NET应用程序中存在内存问题,在初始化和加载所有内容之后,我的应用程序开始在Gen2堆中消耗大约1GB。 It slowly over time (4-5 hours) ends up consuming 4GB in the Gen2 heap. 它随着时间的推移(4-5小时)慢慢消耗Gen2堆中的4GB。 I've used WinDbg to analyze things that I see that some of my object types (and associated memory usage) are increasing. 我已经使用WinDbg来分析我看到的一些对象类型(以及相关的内存使用情况)正在增加的事情。

All of the objects that growing in instances (and mem usage) are referenced by the same parent object type. 实例中增长的所有对象(和mem用法)都由相同的父对象类型引用。 This parent object type has about 3900 instances - this never changes. 此父对象类型有大约3900个实例 - 这永远不会更改。 Somehow, I'm adding child objects to some of these parent instances, but I don't have a good way to see which of the 3900 instances are being added to. 不知何故,我正在将子对象添加到其中一些父实例中,但我没有很好的方法来查看正在添加的3900个实例中的哪一个。

!DumpHeap -mt will show me all my parent types, but the sizes are all the same because it doesn't count children. !DumpHeap -mt会显示我所有的父类型,但大小都是一样的,因为它不计算孩子。

!ObjSize will count the size of the children too, but will only take one object at a time for an argument (or all objects of all types - not just my parent type - which is way too many objects) !ObjSize也将计算子项的大小,但一次只能获取一个参数(或所有类型的所有对象 - 不仅仅是我的父类型 - 这是太多的对象)

Looking at the child objects and tracing them back to the parent isn't helpful either because there are a couple million of these types and I don't see a way to do some kind of aggregate trace. 查看子对象并将它们追溯到父对象是没有用的,因为有几百万种这样的类型,我没有看到某种方式来进行某种聚合跟踪。

Tools like CLRProfiler and ANTS slow down my app too much (ANTS less so) to make the problem happen in any reasonable amount of time. 像CLRProfiler和ANTS这样的工具会使我的app太慢(ANTS不那么频繁),以便在任何合理的时间内解决问题。

I have tried running my application with a small subset of data that it normally runs on in order to make debugging easier, but I don't get memory issues here. 我已经尝试使用它通常运行的一小部分数据来运行我的应用程序,以便使调试更容易,但我不会在这里遇到内存问题。 I think there are some edge cases in my entire data set that cause strange things, but I don't know what those edge cases are in order to isolate them into a subset of my entire data set. 我认为在我的整个数据集中存在一些引起奇怪事情的边缘情况,但我不知道这些边缘情况是什么,以便将它们隔离成我的整个数据集的子集。

Have read widely on this and can't see anyone suggesting what to do when are LOTS of objects in Gen2 that are supposed to be there and a small amount of objects of the same type that keep increasing. 已经广泛阅读并且看不到任何人建议在Gen2中有多少物体应该在那里做什么以及少量相同类型的物体不断增加时。

Any tips would be most appreciated. 任何提示将非常感激。

Interesting puzzle. 有趣的谜题。 As you know, objects get promoted to gen2 when they've survived collections because they're referenced by something that lives a long time. 如你所知,当对象幸存下来时,它们会被提升为gen2,因为它们被长期存在的东西所引用。 You don't say what kind of application this is - asp.net, WPF, winforms, etc. so we'll have to make some guesses. 你没有说这是什么样的应用程序 - asp.net,WPF,winforms等等所以我们必须做出一些猜测。

One strategy you could try is logging. 您可以尝试的一种策略是记录。 You say there are 3900 instances of a 'parent object' that something is getting added to - can you instrument the method on the parent object that accepts the new objects? 你说有3900个“父对象”实例,有些东西被添加到 - 你可以在接受新对象的父对象上检测方法吗? Maybe by logging those additions you can get an idea of where they're coming from. 也许通过记录这些新增内容,您可以了解它们的来源。

I assume you're using SOS for this. 我假设您正在使用SOS。 A better option would be to use PSSCOR2 or PSSCOR4 (depending on which version of the runtime you're on). 更好的选择是使用PSSCOR2PSSCOR4 (取决于您所使用的运行时版本)。 The PSSCOR version of !dumpheap has an additional delta column, which might help you detect which instances are growing over time. !dumpheap的PSSCOR版本有一个额外的delta列,可以帮助您检测哪些实例随时间增长。

You can use !objsize on all objects of your parent type 您可以在父类型的所有对象上使用!objsize

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

or by method table if your class name is not unique enough 或者通过方法表,如果您的类名不够独特

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM