Java 雅各布没有';不要正确地释放物体
我有一个eclipse插件,它使用Jacob连接到COM组件。但是在我完全关闭插件之后,.exe文件仍然挂在Windows进程中 我使用Java 雅各布没有';不要正确地释放物体,java,com,jacob,Java,Com,Jacob,我有一个eclipse插件,它使用Jacob连接到COM组件。但是在我完全关闭插件之后,.exe文件仍然挂在Windows进程中 我使用ComThread.InitMTA(true)进行初始化,并确保在关闭应用程序之前为我创建的每个COM对象调用SafeRelease(),最后调用ComThread.Release() 我有什么事情没做吗?TD2JIRA转换器也有同样的问题。最终不得不修补其中一个Jacob文件以释放对象。在那之后一切都很顺利 my client logout()方法中的代码现在
ComThread.InitMTA(true)
进行初始化,并确保在关闭应用程序之前为我创建的每个COM对象调用SafeRelease()
,最后调用ComThread.Release()
我有什么事情没做吗?TD2JIRA转换器也有同样的问题。最终不得不修补其中一个Jacob文件以释放对象。在那之后一切都很顺利 my client 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调用了native method release(),但内存(甚至不是Java内存,而是JVM进程内存)仍无法控制地增长。一些进一步的建议:
ComThread.Release()
的调用移动到finally
块中,否则如果引发异常,线程将保持连接状态ComThread.InitMTA
和ComThread.Release
。如果您忘记在工作线程中执行此操作,那么该线程将自动连接,而不会分离InitSTA
并坚持InitMTA
。即使只有一个线程使用COM,我也发现InitSTA
是脆弱的。我不知道JACOB的内部编组机制是如何工作的,但我最终得到了“ghost”对象,这些对象看起来有效,但在调用它们的方法时却什么都不做幸运的是,我从未需要修改JACOB库中的任何代码。我自己也遇到过这个问题。在搞乱了initMTA等之后,我发现了一个简单的修复方法-启动Java时,在命令行中添加以下内容: -Dcom.jacob.autogc=true 这将导致ROT类使用WeakHashMap而不是HashMap,从而解决问题
您还可以使用-Dcom.jacob.debug=true来查看大量信息性的调试输出,并查看ROT映射的大小 感谢弗拉基米尔的反馈。我使用了一个测试应用程序,并且.exe在测试应用程序关闭后立即关闭。对于Jacob,您的解决方案似乎可以正常工作,.exe在5分钟内被删除,在此期间在任务管理器中看不到内存使用情况的更改。5分钟的持续时间正常吗?也许是雅各布的问题?我不得不承认,这个解决方案是基于直觉的(经过多次尝试),我不知道如何支持或解释它(还记得你是如何修补jacob文件的吗?即使使用InitMTA和正确的打开/关闭顺序,我发现内存消耗得相当快。因此,我现在要做的是生成一个处理DCOM通信的子进程,并通过文本协议与它通信。当特定数量的调用通过时,我无情地杀死它并重新启动它.谢天谢地,我使用的服务器允许这样做。