JACOB doesn't release the objects properly

2019-02-11 03:13发布

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?

标签: java com jacob
3条回答
啃猪蹄的小仙女
2楼-- · 2019-02-11 03:25

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.

查看更多
爷、活的狠高调
3楼-- · 2019-02-11 03:35

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.

查看更多
我只想做你的唯一
4楼-- · 2019-02-11 03:47

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.

查看更多
登录 后发表回答