我的记忆在哪里?大的私有字节数

时间:2009-06-10 07:13:05

标签: .net wpf debugging memory-leaks

我有一个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

5 个答案:

答案 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测试的页面运行应用程序)

<强>之前:

  • app app:63 Mb
  • 应用后使用: 177 Mb

<强>后:

  • app app:53 Mb
  • 应用后使用: 97 Mb

我会发现更多答案! (我认为最简单的读者可以将我的发现视为单独的答案,而不是回复评论 - 好吗?)

[1]:参考:http://groups.google.com/group/wpf-disciples/web/wpf-and-xaml-coding-guidelines?pli=1