【发布时间】:2014-07-07 13:34:36
【问题描述】:
我们的应用程序设置了一个 AppDomain,我们将一些模块加载到其中。其中一个模块是使用传统的混合模式 DLL 与 H5 文件进行交互。问题在于,一旦加载了混合模式 DLL,就会在新的 AppDomain 中以及在应用程序启动时创建的原始 AppDomain 中放置一个句柄。
当我们卸载该 AppDomain 时,新 AppDomain 中的句柄自然会消失,但原始 AppDomain 中的句柄仍然存在并被固定。这会导致我们的托管堆碎片化。
我在混合模式源代码中找不到任何可以解释此行为的内容。唯一看起来可疑的是以下使用本机静态字符串的调用:
H5Utils::throwError( String^ message ) {
String^ stackStr = gcnew String( H5Utils::errorStack_.c_str() );
String^ myMessage = message + "\n\nError stack: " + stackStr;
throw gcnew H5IOError( myMessage );
}
其中H5Utils::errorStack_.c_str() 是本机静态字符串。但是这个方法永远不会被调用,并且在加载混合模式 DLL 时,模块会立即加载到两个 AppDomains 中。
有谁知道为什么要在两个 AppDomain 中创建句柄?
【问题讨论】:
-
好吧,不是这样。您将需要可用的 !gchandles 命令from the SOS debugger extension 来了解更多信息。
-
谢谢,但是我不明白这对我有什么帮助。我已经知道我的手柄泄漏了。问题是为什么会发生这种情况,为什么在原始 AppDomain 和我为加载混合模式模块而创建的 AppDomain 中都设置了句柄。
-
如果你不知道这个句柄是什么类型的对象,那么你就无法知道它是在哪里以及为什么被创建的。
标签: c# appdomain mixed-mode