2

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

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

我会留下一些未完成的事情吗?

4

3 回答 3

6

一些进一步的建议:

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

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

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

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

于 2009-09-19T10:14:50.687 回答
6

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

这将导致 ROT 类使用 Wea​​kHashMap 而不是 HashMap,从而解决了问题。

您还可以使用 -Dcom.jacob.debug=true 查看大量信息丰富的调试信息并查看 ROT 映射的大小。

于 2009-12-02T21:14:16.443 回答
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();
}

AFAIR 最初无法访问 ROT 类。

更新

Jacob中释放资源的正确方法是调用

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

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

于 2009-06-11T12:11:15.010 回答