此应用程序存在内存泄漏并经常使浏览器崩溃。通过反复打开和关闭应用程序中的一项功能,我可以很快增加它的内存使用量。使用 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 中的元素较少,那么表和它所引用的非托管内存量都会增长得更慢。