JACOB 没有正确释放对象

发布于 2024-07-24 15:40:32 字数 224 浏览 7 评论 0原文

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

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

我是否留下了一些未完成的事情?

I have an eclipse plugin, which connects to a COM component using Jacob. But after I close the plugin entirely, the .exe file stays hanging in Windows processes.

I use ComThread.InitMTA(true) for initialization and make sure that SafeRelease() is called for every COM object I created before closing the app and I call ComThread.Release() at the very end.

Do I leave something undone?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

笑着哭最痛 2024-07-31 15:40:32

一些进一步的建议:

  1. 将对 ComThread.Release() 的调用移至 finally 块中,否则如果抛出异常,线程将保持附加状态。

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

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

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

Some further suggestions:

  1. Move the call to ComThread.Release() into a finally block, otherwise the thread will remain attached if an exception is thrown.

  2. Check that you are calling ComThread.InitMTA and ComThread.Release in every thread that uses a COM object. If you forget to do this in a worker thread then that thread will be attached automatically and never detached.

  3. Avoid InitSTA and stick to InitMTA. Even when there is only one thread using COM, I have found InitSTA to be flaky. I don't know how JACOB's internal marshalling mechanism works but I have ended up with "ghost" objects that appear to be valid but do nothing when their methods are invoked.

Fortunately I have never yet needed to modify any code in the JACOB library.

樱&纷飞 2024-07-31 15:40:32

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

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

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

I ran into this issue myself. After messing with initMTA,etc. I found a simple fix - when you start Java add the following to your command line:
-Dcom.jacob.autogc=true

This will cause the ROT class to use a WeakHashMap instead of a HashMap and that solves the problem.

You can also use -Dcom.jacob.debug=true to see lots of informative debug spew and watch the size of the ROT map.

月亮是我掰弯的 2024-07-31 15:40:32

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();

Bad thing,但有时它并没有帮助。 尽管Jacob调用了native方法release(),但是内存(甚至不是Java内存,而是JVM进程内存)仍然不受控制地增长。

Had the same problem with TD2JIRA converter. Eventually had to patch one of the Jacob files to release the objects. After that all went smooth.

The code in my client logout() method now looks like this:

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();
}

The ROT class wasn't accessible initially, AFAIR.

Update

The correct way to release resources in Jacob is to call

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

Bad thing though is that sometimes it doesn't help. Despite Jacob calls native method release(), the memory (not even Java memory, but JVM process memory) grows uncontrollably.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文