Java 雅各布没有';不要正确地释放物体

Java 雅各布没有';不要正确地释放物体,java,com,jacob,Java,Com,Jacob,我有一个eclipse插件,它使用Jacob连接到COM组件。但是在我完全关闭插件之后,.exe文件仍然挂在Windows进程中 我使用ComThread.InitMTA(true)进行初始化,并确保在关闭应用程序之前为我创建的每个COM对象调用SafeRelease(),最后调用ComThread.Release() 我有什么事情没做吗?TD2JIRA转换器也有同样的问题。最终不得不修补其中一个Jacob文件以释放对象。在那之后一切都很顺利 my client logout()方法中的代码现在

我有一个eclipse插件,它使用Jacob连接到COM组件。但是在我完全关闭插件之后,.exe文件仍然挂在Windows进程中

我使用
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
    块中,否则如果引发异常,线程将保持连接状态

  • 检查是否正在使用COM对象的每个线程中调用
    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通信的子进程,并通过文本协议与它通信。当特定数量的调用通过时,我无情地杀死它并重新启动它.谢天谢地,我使用的服务器允许这样做。