我有一个用VC++ MFC 6.0编写的应用程序。最近通过在 vs2008 中编译升级到 .NET 3.5,并使用托管和非托管环境向其添加了一些 WPF 应用程序。基本上在win32窗口上托管WPF。如果我只是打开一个 WPF 应用程序窗口,内存会不断增加,大约 1KB/10 秒。我尝试过使用.NET Memory profiler和Ants内存分析器。但两者都不能帮助我检测泄漏!!我已从托管的 WPF 应用程序中删除了所有 WPF 控件。它只包含一个框架的页面。但泄漏仍然发生!!有人能帮我什么可能导致应用程序内存增加吗?
首先,应确定是否存在托管内存泄漏或本机内存泄漏:
使用这些 PerfMon 计数器来执行此操作:
- 进程/专用字节,
- .NET CLR 内存/# 所有堆中的字节,
- .NET CLR LocksAndThreads/# of current logical Threads.
如果 1 正在增加,但 2 保持稳定,则存在本机内存泄漏。如果 1 和 2 正在增加,则存在托管内存泄漏。
如果 3 意外增加,则线程堆栈泄漏。
如果您发现托管内存泄漏,.NET 内存探查器工具(如 Ants、YourKit 等)应该会有所帮助。由于它们在您的情况下没有帮助,因此您可能有本机泄漏。
重要提示:请确保在查看内存消耗之前手动调用垃圾回收器。如果没有足够的内存压力,GC 将无法运行,并且进程的内存会增加(在这种特殊情况下不是泄漏)。像这样调用 GC
:GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
本文介绍了 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,但选择不同的类/实例。
好吧,经过一番反省,发现泄漏实际上是由于框架中的错误造成的。阅读此内容了解更多信息http://social.msdn.microsoft.com/Forums/zh/wpf/thread/5b9ae245-9067-4ca4-b846-180db9f7bde5