题
我有一个 Eclipse 插件,它使用 Jacob 连接到 COM 组件。但在我完全关闭插件后,.exe 文件仍挂在 Windows 进程中。
我用 ComThread.InitMTA(true)
进行初始化并确保 SafeRelease()
为我在关闭应用程序之前创建的每个 COM 对象调用,并且我调用 ComThread.Release()
在最后。
我是否留下了一些未完成的事情?
解决方案
曾与TD2JIRA转换器相同的问题。最终不得不修补雅各文件释放的对象之一。在那之后一切顺利平稳。
在我的客户端注销的代码()方法现在看起来像这样:
try {
Class rot = ROT.class;
Method clear = rot.getDeclaredMethod("clearObjects", new Class[]{});
clear.setAccessible(true);
clear.invoke(null, new Object[]{});
} catch( Exception ex ) {
ex.printStackTrace();
}
在ROT类是不可访问最初,AFAIR。
<强>更新强>
以释放资源在雅各正确的方法是调用
ComThread.InitSTA(); // or ComThread.InitMTA()
...
ComThread.Release();
坏事是,虽然有时候它并不能帮助。尽管雅各布调用本机方法释放(),存储器(即使不是Java存储器,但JVM进程存储器)不受控制地生长。
其他提示
一些进一步的建议:
将呼叫移至
ComThread.Release()
变成一个finally
阻塞,否则如果抛出异常,线程将保持附加状态。检查您是否正在拨打电话
ComThread.InitMTA
和ComThread.Release
在每个使用 COM 对象的线程中。如果您忘记在工作线程中执行此操作,则该线程将自动附加并且永远不会分离。避免
InitSTA
并坚持InitMTA
. 。即使只有一个线程使用 COM,我也发现InitSTA
变得脆弱。我不知道 JACOB 的内部编组机制是如何工作的,但我最终得到了“幽灵”对象,这些对象看起来有效,但在调用它们的方法时什么也不做。
幸运的是,我从来不需要修改 JACOB 库中的任何代码。
我就遇到了这个问题我自己。与initMTA等搞乱了。我发现了一个简单的解决方法 - 当您启动Java以下内容添加到您的命令行: -Dcom.jacob.autogc =真
这将导致ROT类使用WeakHashMap中代替一个HashMap的和解决该问题。
您也可以使用-Dcom.jacob.debug = true可看到大量翔实的调试喷出并观看ROT地图的大小。