可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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?
回答1:
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.
回答2:
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.
回答3:
Some further suggestions:
Move the call to ComThread.Release()
into a finally
block, otherwise the thread will remain attached if an exception is thrown.
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.
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.