lil*_*rne 7 mfc memory-leaks cdialog visual-studio-2010 visual-c++
我们正在从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;
}
Run Code Online (Sandbox Code Playgroud)
内存使用率不断上升,我们使用大约30个按钮的示例对话框泄漏了Mb的10s.
请注意,上面是一个测试示例,我们已经删除了所有对话框处理代码,在我们的实际代码中,我们有一个派生类并使用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;
}
Run Code Online (Sandbox Code Playgroud)
我们在这里失踪了什么?
这似乎取决于MFC管理其句柄映射的方式:
从CWnd :: FromHandle获得的CWnd的生命周期是多少?
如果你等待的时间足以让你的应用程序变得空闲,那么你确实会恢复你的记忆,即它不是真正的泄漏.但是,正如您所观察到的,虽然Visual C++ 2010继续消耗越来越多的内存 - 直到地图在OnIdle()中整理 - 这似乎不会发生在Visual C++ 2008中.
调试包含代码的应用程序确实显示VC 10版本的HWND临时映射中的对象比VC 9版本中的对象多得多.
句柄映射代码(winhand.cpp)似乎没有在两个版本之间发生变化,但MFC中有很多代码使用它!
无论如何,假设你真的想要像这样运行你的程序 - 我猜你在某种自动模式下运行? - 然后你会想要以适当的间隔强制垃圾收集.在MSDN上查看此条目:
http://msdn.microsoft.com/en-us/library/xt4cxa4e(v=VS.100).aspx
CWinThread :: OnIdle()实际上调用它来整理东西:
AfxLockTempMaps();
AfxUnlockTempMaps(/*TRUE*/);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1667 次 |
| 最近记录: |