JACOB不会正确释放对象

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

我使用ComThread.InitMTA(true)进行初始化,并确保在关闭应用程序之前为我创建的每个COM对象调用ComThread.Release() ,并在最后调用ComThread.Release()

我是否会遗漏一些东西?

与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。

更新

在雅各布释放资源的正确方法是打电话

 ComThread.InitSTA(); // or ComThread.InitMTA() ... ComThread.Release(); 

不好的是,有时它没有帮助。 尽管Jacob调用本机方法release(),但内存(甚至不是Java内存,但JVM进程内存)也无法控制地增长。

我自己遇到了这个问题。 乱搞initMTA后等。 我发现了一个简单的修复 – 当你启动Java时,在命令行中添加以下内容:-Dcom.jacob.autogc = true

这将导致ROT类使用WeakHashMap而不是HashMap来解决问题。

您还可以使用-Dcom.jacob.debug = true来查看大量信息性调试,并观察ROT地图的大小。

进一步的建议:

  1. ComThread.Release()的调用移到finally块中,否则如果抛出exception,线程将保持连接状态。

  2. 检查您是否在使用COM对象的每个线程中调用ComThread.InitMTAComThread.Release 。 如果您忘记在工作线程中执行此操作,则该线程将自动附加并且永不分离。

  3. 避免使用InitSTA并坚持使用InitMTA 。 即使只有一个线程使用COM,我发现InitSTA是片状的。 我不知道JACOB的内部编组机制是如何工作的,但我最终得到的“ghost”对象似乎是有效的,但在调用它们的方法时什么都不做。

幸运的是,我从未需要修改JACOB库中的任何代码。