我有一个eclipse插件,它使用Jacob连接到COM组件。但是在我完全关闭插件之后,.exe文件仍停留在Windows进程中。
我使用ComThread.InitMTA(true)
进行初始化,并确保在关闭应用之前为我创建的每个COM对象调用SafeRelease()
,并在最后调用ComThread.Release()
。
我要撤消一些事吗?
答案 0 :(得分:6)
一些进一步的建议:
将对ComThread.Release()
的调用移至finally
块,否则如果抛出异常,该线程将保持附加状态。
检查您是否在使用COM对象的每个线程中调用ComThread.InitMTA
和ComThread.Release
。如果您忘记在工作线程中执行此操作,则该线程将自动附加且永不分离。
避免InitSTA
并坚持InitMTA
。即使只有一个线程使用COM,我发现InitSTA
是片状的。我不知道JACOB的内部编组机制是如何工作的,但我最终得到的“鬼”对象似乎是有效的,但在调用它们的方法时什么也不做。
幸运的是,我从未需要修改JACOB库中的任何代码。
答案 1 :(得分:6)
我自己遇到了这个问题。乱搞initMTA后等。我发现了一个简单的修复 - 当你启动Java时,在命令行中添加以下内容: -Dcom.jacob.autogc =真
这将导致ROT类使用WeakHashMap而不是HashMap,并解决了这个问题。
您还可以使用-Dcom.jacob.debug = true查看大量信息性调试,并观察ROT地图的大小。
答案 2 :(得分:5)
与TD2JIRA转换器有同样的问题。最终必须修补其中一个Jacob文件以释放对象。之后一切顺利。
我的客户端logout()方法中的代码现在看起来像这样:
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。
<强>更新强>
在Jacob中释放资源的正确方法是调用
ComThread.InitSTA(); // or ComThread.InitMTA()
...
ComThread.Release();
不好的是,有时它没有帮助。尽管Jacob调用了本机方法release(),但内存(甚至不是Java内存,但是JVM进程内存)也无法控制地增长。