2

此应用程序存在内存泄漏并经常使浏览器崩溃。通过反复打开和关闭应用程序中的一项功能,我可以很快增加它的内存使用量。使用 ANTS Memory Profiler,我发现了一个神秘的不断增长的字典,我认为我的应用程序的代码不是直接实例化或引用的。任何人都可以提供对这本词典的见解,和/或关于下一步做什么以阻止泄漏的建议吗?

分析器说非托管内存增长最快。它有时还会给我一个内存碎片警报,“内存碎片正在限制可以分配的对象的大小”或“内存碎片正在影响可以分配的最大对象的大小”。

大对象堆上最大的对象是一个被 a 使用的数组Dictionary<IntPtr, Object>,它主要包含 WeakReferences。我认为随着这个字典的增长,它不得不重新分配它的内部数组(如这里的备注部分所述);并且由于 GC 从不压缩 LOH,我一定会得到碎片。

我还想知道这个字典是否连接到非托管内存增加,因为字典键是 IntPtrs。在 Tess Ferrandez 的博客文章的帮助下,我运行了 DebugDiag 几次,但这给了我很多我不知道如何分析的有趣信息。基本上,大部分内存分配是由npctrl!CWindowsServices::OSMemoryAllocate和完成的coreclr:CExecutionEngine::ClrVirtualAlloc。如果有人认为这会有所帮助,也许我可以提供内存压力分析和/或 .dmp 文件。

[更新]我认为这可能是 ManagedPeerTable。另请参阅下面的更新。[/更新]

以下是 ANTS 的一些屏幕截图。第一个来自一个会话,其余的都来自另一个会话。

内存碎片

内存变化概览

LOH 上大小变化最大的类型是字典条目数组。

大对象堆上的对象列表

这是字典条目引用的列表,其中大部分是 WeakReference 实例。

字典条目引用的对象

包含这些条目的字典本身就存在于对象数组中。

字典条目数组的保留图

对象数组似乎包含与 UI 相关的对象。

包含不断增长的字典的对象数组的内容

泄漏功能有很多与之相关的 XAML,包含几个自定义控件、模板、样式和高度自定义的RadGridView。所以接下来我想我将反复删除 XAML 的片段并重新测试,希望我能缩小可能的罪魁祸首的简短列表。

更新:

我删除的 XAML 越多,泄漏就越慢。我发现该功能的 UI 元素没有被清理,所以接下来我需要找出原因。

MS.Internal.ManagedPeerTable 静态类有一个私有字段 type Dictionary<IntPtr, object>,我敢打赌这就是我在这里看到的。显然,它用于维护非托管对象与其所代表的托管对象之间的链接。(另请参阅底部附近的此链接。)因此,如果我的 XAML 中的元素较少,那么表和它所引用的非托管内存量都会增长得更慢。

4

1 回答 1

0

我发现了漏洞并通过升级到最新版本的 Telerik RadControls 来修复它。RadTreeView 中存在内存泄漏,已在Q3 2012 SP1 版本中修复。RadTreeView 间接引用了我的 UI 的主 UserControl,因此我的 UI 中的每个控件和资源也都在内存中徘徊。

前: 从 UI 中删除 RadTreeView 之前的私有字节图

后: 从 UI 中删除 RadTreeView 后的私有字节图

此外,LOH 上的字典和非托管内存都没有像以前那样增长。我猜想字典是 ManagedPeerTable 使用的字典,虽然我很惊讶它出现在对象数组中而​​不是作为 GC 根。

于 2013-03-08T14:47:48.770 回答