我有一个eclipse插件,它使用Jacob连接到COM组件。但是完全关闭插件之后,.exe文件仍停留在Windows进程中。JACOB没有正确释放对象
我使用ComThread.InitMTA(true)
进行初始化,并确保SafeRelease()
为我在关闭应用程序之前创建的每个COM对象调用,我最后调用ComThread.Release()
。
我是否有遗漏某些东西?
我有一个eclipse插件,它使用Jacob连接到COM组件。但是完全关闭插件之后,.exe文件仍停留在Windows进程中。JACOB没有正确释放对象
我使用ComThread.InitMTA(true)
进行初始化,并确保SafeRelease()
为我在关闭应用程序之前创建的每个COM对象调用,我最后调用ComThread.Release()
。
我是否有遗漏某些东西?
与TD2JIRA转换器有同样的问题。最终不得不修补其中一个Jacob文件来释放这些对象。之后,一切顺利。
在我的客户端退出的代码()方法现在看起来是这样的:
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();
坏事是,虽然有时候它并不能帮助。尽管Jacob调用了本地方法release(),但内存(甚至不是Java内存,但是JVM进程内存)却无法控制地增长。
一些进一步的建议:
移动调用ComThread.Release()
成finally
块,否则,如果有异常抛出该线程将保持连接。
检查您是否在每个使用COM对象的线程中调用ComThread.InitMTA
和ComThread.Release
。如果您忘记在工作线程中执行此操作,那么该线程将自动连接并永不分离。
避免InitSTA
并坚持InitMTA
。即使只有一个线程使用COM,我发现InitSTA
是片状的。我不知道JACOB的内部编组机制是如何工作的,但我最终得到的“鬼”对象似乎是有效的,但在调用它们的方法时什么也不做。
幸运的是,我从来没有需要修改JACOB库中的任何代码。
我自己遇到了这个问题。在和initMTA混淆之后,等等。我发现了一个简单的解决方法 - 当您启动Java以下内容添加到您的命令行: -Dcom.jacob.autogc =真
这将导致ROT类使用WeakHashMap中,而不是一个HashMap和解决该问题。
您也可以使用-Dcom.jacob.debug = true来查看大量有用的调试信息并观察ROT地图的大小。
感谢弗拉基米尔的反馈意见。 我使用了一个测试应用程序,并在测试应用程序关闭后立即关闭.exe。对于雅各布,您的解决方案似乎可行,5分钟内即可删除.exe,并且在任务管理器中没有发现内存使用情况的变化。持续5分钟的持续时间是否正常?也许是雅各布的问题? – Gorro 2009-06-11 13:38:07
我不得不承认,解决方案是基于直觉的(经过多次尝试),而且我没有任何支持或解释它的知识。 :( – 2009-06-11 15:28:54