我们正在从VC8升级到VC10,并发现了一些似乎与CDialog相关的内存泄漏。下面的代码演示了最简单的示例,它使用一个只有几个按钮的CDialog。在VC10中会泄漏,但在VC8中不会:
for (int i = 0; i < 5000; ++i) {
CDialog* dialog = new CDialog;
dialog->Create(IDD_LEAKER, 0);
dialog->DestroyWindow();
delete dialog;
}内存使用率一直在上升,我们有大约30个按钮的示例对话框泄漏了10 Mb。
请注意,上面是一个测试示例,其中我们剥离了所有的对话处理代码,在我们的实际代码中,我们有一个派生类并使用PostNcDestroy()。
奇怪的是,以下两个代码示例都没有在VC8或VC10中泄漏:
CDialog* dialog = new CDialog;
for (int i = 0; i < 5000; ++i) {
dialog->Create(IDD_LEAKER, 0);
dialog->DestroyWindow();
}
delete dialog;
for (int i = 0; i < 5000; ++i) {
CDialog* dialog = new CDialog;
delete dialog;
}我们在这里遗漏了什么?
发布于 2011-08-19 17:41:23
这似乎与MFC管理其句柄映射的方式有关:
What is the lifetime of a CWnd obtained from CWnd::FromHandle?
如果你等待你的应用程序空闲的时间足够长,你就会得到你的内存,也就是说,这并不是一个真正的漏洞。然而,正如您所观察到的,虽然Visual C++ 2010继续消耗越来越多的内存-直到在OnIdle()中整理好地图-但这似乎不会在Visual C++ 2008中发生。
调试包含您的代码的应用程序确实表明,VC10版本的HWND临时映射中的对象比VC9版本中的对象多得多。
句柄映射代码(winhand.cpp)似乎在两个版本之间没有变化,但是MFC中有很多使用它的代码!
无论如何,假设你真的想要像这样运行你的程序--我猜你是在某种自动化模式下运行的--那么你就会想要以适当的时间间隔强制执行垃圾收集。看看MSDN上的这个条目:
http://msdn.microsoft.com/en-us/library/xt4cxa4e(v=VS.100).aspx
CWinThread::OnIdle()实际上会调用它来整理东西:
AfxLockTempMaps();
AfxUnlockTempMaps(/*TRUE*/);https://stackoverflow.com/questions/7107591
复制相似问题