我有一个WPF应用程序,其中包括显示大量和小的图像。 我的问题是该应用程序使用了大量内存,我无法弄清楚它来自何处。
这个场景,当给应用程序施加压力时,我会在perfmon中得到这个图:
http://www.imagechicken.com/uploads/1244548604007097000.jpg
黑色大行是Process \ Private字节,其他行是CLR mem计数器(粉红色的是总提交字节)
图中的数字是:
专用字节~350 Mb
承诺字节数~100 Mb
我一直在使用WinDbg和其他工具进行大量挖掘,他们都报告托管堆栈的行为(!eeheap报告总管理堆栈大约100 Mb)
我一直在寻找像LeakDiag,LDGrapher这样的应用,却一无所获。
所以,最后我的问题是,如何继续寻找记忆的去向?
即使启动应用程序也会使用100Mb的提交字节,但190Mb的私有字节。
参考文献:
我已经在很多网站上阅读了很多相关内容:
Tess Ferrandez:http://blogs.msdn.com/tess/archive/2009/02/27/net-memory-leak-reader-email-are-you-really-leaking-net-memory.aspx
Rico Mariani:http://blogs.msdn.com/ricom/archive/2004/12/10/279612.aspx
MSDN mag:http://msdn.microsoft.com/en-us/magazine/cc163528.aspx
答案 0 :(得分:4)
我在WPF应用程序中遇到了类似的问题,并且used UMDH to track在其中分配了本机内存。 (请注意,set _NT_SYMBOL_PATH从OS组件中获取良好的堆栈跟踪通常很有帮助。
日志显示几乎所有内存都分配在视频驱动程序中。我发现司机已经过了一年多了;我从制造商的网站上安装了最新版本,解决了这个问题。
答案 1 :(得分:3)
仅仅因为您的应用程序使用大量内存并不一定意味着您有内存泄漏。根据你问题中的信息,很难断言可能出错的地方。
使用WinDbg对托管内存泄漏进行故障排除时,请执行以下操作:
使用!eeheap
概述堆使用情况(这会报告堆使用情况,而不是您提到的堆栈 - 每个堆栈的默认大小为1 MB,因此,除非您更改了此内容,否则你无法在堆栈上使用100 MB)
执行!dumpheap -stat
以查找堆上的内容。如果你有内存泄漏,有罪的类型将是最大的消费者之一。要了解堆使用情况如何发展,您可以恢复应用程序,稍后再破解它,然后重复!dumpheap -stat
命令。
如果您发现任何类型的实例多于您的实例,请使用!dumpheap -mt <MT of type>
列出实例。这将列出特定类型的所有实例。使用!gcroot
命令选择随机实例并检查根。这将告诉您是什么让有问题的实例保持活力。如果没有root,则会在某个时刻收集这些实例。
更新以回复您的意见:
托管堆只是托管应用程序内存占用的一部分。请记住,.NET应用程序实际上是另一个应用程序中的应用程序 - 主机进程,它加载CLR,然后CLR加载您的应用程序。因此,在您的应用程序开始使用任何内存之前,CLR已经占有一席之地。除此之外,.NET应用程序将MSIL代码和JIT编译代码存储为脚印的一部分。 CLR也为各种簿记内容占用空间(例如,CLR创建了两个额外的AddDomains供内部使用)。
你提供的数字并没有让我觉得过分,但由于我不知道你的应用程序,很难说它是否过多。
托管堆上的100 MB可能没问题,具体取决于您的应用程序正在执行的操作。你检查堆了吗?如果是这样你发现了什么?
答案 2 :(得分:1)
从Scitech下载MemProfiler。它有14天的试用版。
您报告的问题通常是由于视图/资源由于在堆中具有根而无法处理。一个常见的原因不是无线事件处理程序。
答案 3 :(得分:1)
您可能想尝试阅读this article in the latest MSDN magazine。它详细介绍了如何使用VADump来更多地了解进程内存的用途。
您可以在此处下载VADump:http://go.microsoft.com/fwlink/?LinkId=149683
要分解托管堆,您可以尝试使用内存分析器。我个人喜欢JetBrains dotTrace。
答案 4 :(得分:0)
一个答案:它过多地合并了ResourceDictionaries(一个WPF的东西)
详细信息:为了能够在Blend和VS中看到设计时的设计,我们曾经在大多数xaml页面上合并我们的主题资源字典。 这导致为每个控件加载所有资源的副本,更多信息可以在这里阅读:[WPF Disciples] [1]
所以我现在合并它们的唯一地方是App.xaml.cs:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="pack://application:,,,/Company.Themes;Component/AppTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
结果:(通过一些带有自动GUI测试的页面运行应用程序)
<强>之前:强>
<强>后:强>
我会发现更多答案! (我认为最简单的读者可以将我的发现视为单独的答案,而不是回复评论 - 好吗?)
[1]:参考:http://groups.google.com/group/wpf-disciples/web/wpf-and-xaml-coding-guidelines?pli=1