2012-04-19 24 views
1

我的混合模式MFC应用程序正在创建错误的内存泄漏,因为在MFC dll关闭之前CRT没有时间关闭。混合模式C++/CLI应用程序没有正确关闭CLR

我有一个非常简单的小应用程序,显示问题:

#include <windows.h> 
#include <iostream> 

struct LongTimeToDestroy 
{ 
    ~LongTimeToDestroy() 
    { 
    std::cout << "Will get called!" << std::endl; 
    Sleep(3000); 
    std::cout << "Won't get called!" << std::endl; 
    } 
}; 

LongTimeToDestroy gJamsUpTheCRT; 

int main() 
{ 
} 

编译cl.exe /clr test.cpp。在运行时,你会得到:

Will get called! 

问题的症结是:gJamsUpTheCRT之前,宣称任何静态/全局变量不会被释放。例如,在我的情况下,MFC CWinApp派生的类不会被清理。

这是预期的行为?我想让我的应用完全关闭。

感谢,

回答

2

这是预期的行为吗?

是的,尽管您必须阅读CLI规范中的精美打印。它承诺程序终止时调用托管对象的终结器。但有一点需要注意,这样做的终结者线程需要两秒钟才能完成工作。如果需要更长的时间,那么CLR会假设有一些严重错误。就像在无法获得信号的同步对象上进行代码阻塞的常见诅咒一样。它由处理终止器线程并允许程序终止。没有诊断。

你必须解决这个限制。

+0

Porges链接中提供的Joe Duffy链接指出:“虽然可配置,但默认情况下CLR会让终结器运行2秒”。你知道如何配置这个吗? – Cechner 2012-04-19 00:52:10

+0

否。除了自己托管CLR,也许。实际上,当你的终结者已经烧掉了50亿个CPU周期并且没有完成工作,那么增加一些更不可能带来救济。 – 2012-04-19 01:10:00

1

我相信this answers your problem

相关的文字:

虽然配置,默认情况下,CLR会让终结了越来越不耐烦2秒之前的运行;如果超过此超时,终止器线程将停止,并且关闭继续,而不会耗尽终止器队列的其余部分。

所以你真的不应该有任何析构函数执行任务,需要时间。

编辑:其实,这不是一个CLR类,所以它不应该在最终化队列?这可能是误导。

+0

这看起来极端 - 这怎么配置?我猜我的情况(MFC静态链接到C++/CLI库)并不常见 - 如果我把所有的C++/CLI的东西放入MFC DLL并链接到该DLL,这是否会纠正? – Cechner 2012-04-19 00:34:42

+0

只需要进一步注意你的编辑:看起来CRT清理是由主模块'.cctor'处理的,我想这个清理是在'finalizer queue'中的某处。 – Cechner 2012-04-19 00:56:49

相关问题