1

我有一个用 VC++ MFC 6.0 编写的应用程序。最近通过在 vs2008 中编译升级到 .NET 3.5,并通过使用托管和非托管环境向其中添加了一些 WPF 应用程序。基本上在win32窗口上托管WPF。如果我只是打开一个 WPF 应用程序窗口,内存会持续增加 1KB/10 秒。我试过使用 .NET 内存分析器和 Ants 内存分析器。但两者都没有帮助我检测泄漏!我已从托管的 WPF 应用程序中删除了所有 WPF 控件。它只包含一个只有一个框架的页面。但泄漏仍然发生!有人请帮我什么可能导致应用程序内存上升?

4

3 回答 3

5

首先,您应该确定是托管内存泄漏还是本机内存泄漏:

使用这些 PerfMon 计数器来执行此操作:

  1. 处理/私有字节,
  2. .NET CLR 内存/# 所有堆中的字节数,
  3. .NET CLR LocksAndThreads/# 当前逻辑线程。

如果 1 增加,但 2 保持稳定,则说明存在本机内存泄漏。如果 1 AND 2 增加,则您有托管内存泄漏。

如果 3 意外增加,则线程堆栈正在泄漏。

如果您发现托管内存泄漏,.NET 内存分析器工具(如 Ants、YourKit 等)应该会有所帮助。由于它们对您的情况没有帮助,因此您可能存在本机泄漏。

重要提示:确保在查看内存消耗之前手动调用垃圾收集器。如果没有足够的内存压力,GC 将不会运行并且您的进程的内存会增加(在这种特殊情况下这不是泄漏。)像这样调用 GC:

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
于 2012-06-15T09:55:41.740 回答
1

本文介绍了 WPF 内存问题的一些常见原因 - 可能值得一读:

http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/learning-memory-management/WPF-Silverlight-pitfalls

关于您使用内存分析器查找泄漏的尝试,请使用 ANTS 尝试以下操作:

1)每隔一分钟或两分钟拍摄两个快照(分析器在每次拍摄快照之前自动运行垃圾收集)。

2) 确保基线快照设置为快照 1,最后一个快照设置为快照 2。

3) 进入班级列表。

4) 在“基本过滤器”下选择“从当前快照仅显示新对象”。

5) 突出显示最大的类,然后转到实例列表。

6) 对于其中一个实例,打开实例保留图,该图显示了将该实例保存在内存中的引用链。

7) 运气好的话,你会看到一个物体抓住了它不应该抓住的东西,然后你可以修复它。如果不是,请重复步骤 5 和 6,但选择不同的类/实例。

于 2012-06-18T11:12:55.567 回答
1

好吧,经过一番反省,发现泄漏实际上是由于框架中的错误造成的。阅读更多信息 http://social.msdn.microsoft.com/Forums/zh/wpf/thread/5b9ae245-9067-4ca4-b846-180db9f7bde5

于 2012-08-03T10:04:08.007 回答