我有一个用 VC++ MFC 6.0 编写的应用程序。最近通过在 vs2008 中编译升级到 .NET 3.5,并通过使用托管和非托管环境向其中添加了一些 WPF 应用程序。基本上在win32窗口上托管WPF。如果我只是打开一个 WPF 应用程序窗口,内存会持续增加 1KB/10 秒。我试过使用 .NET 内存分析器和 Ants 内存分析器。但两者都没有帮助我检测泄漏!我已从托管的 WPF 应用程序中删除了所有 WPF 控件。它只包含一个只有一个框架的页面。但泄漏仍然发生!有人请帮我什么可能导致应用程序内存上升?
3 回答
首先,您应该确定是托管内存泄漏还是本机内存泄漏:
使用这些 PerfMon 计数器来执行此操作:
- 处理/私有字节,
- .NET CLR 内存/# 所有堆中的字节数,
- .NET CLR LocksAndThreads/# 当前逻辑线程。
如果 1 增加,但 2 保持稳定,则说明存在本机内存泄漏。如果 1 AND 2 增加,则您有托管内存泄漏。
如果 3 意外增加,则线程堆栈正在泄漏。
如果您发现托管内存泄漏,.NET 内存分析器工具(如 Ants、YourKit 等)应该会有所帮助。由于它们对您的情况没有帮助,因此您可能存在本机泄漏。
重要提示:确保在查看内存消耗之前手动调用垃圾收集器。如果没有足够的内存压力,GC 将不会运行并且您的进程的内存会增加(在这种特殊情况下这不是泄漏。)像这样调用 GC:
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
本文介绍了 WPF 内存问题的一些常见原因 - 可能值得一读:
关于您使用内存分析器查找泄漏的尝试,请使用 ANTS 尝试以下操作:
1)每隔一分钟或两分钟拍摄两个快照(分析器在每次拍摄快照之前自动运行垃圾收集)。
2) 确保基线快照设置为快照 1,最后一个快照设置为快照 2。
3) 进入班级列表。
4) 在“基本过滤器”下选择“从当前快照仅显示新对象”。
5) 突出显示最大的类,然后转到实例列表。
6) 对于其中一个实例,打开实例保留图,该图显示了将该实例保存在内存中的引用链。
7) 运气好的话,你会看到一个物体抓住了它不应该抓住的东西,然后你可以修复它。如果不是,请重复步骤 5 和 6,但选择不同的类/实例。
好吧,经过一番反省,发现泄漏实际上是由于框架中的错误造成的。阅读更多信息 http://social.msdn.microsoft.com/Forums/zh/wpf/thread/5b9ae245-9067-4ca4-b846-180db9f7bde5