Jacobを使用してCOMコンポーネントに接続するEclipseプラグインがあります。しかし、プラグインを完全に閉じると、.exe ファイルが Windows プロセスでハングしたままになります。
初期化に使用し、アプリを閉じる前に作成したすべての COM オブジェクトに対して呼び出されるComThread.InitMTA(true)
ことを確認し、最後に呼び出します。SafeRelease()
ComThread.Release()
何かやり残したことはありますか?
さらにいくつかの提案:
ComThread.Release()
への呼び出しをfinally
ブロックに移動します。そうしないと、例外がスローされた場合にスレッドがアタッチされたままになります。
COM オブジェクトを使用するすべてのスレッドで呼び出していることを確認してくださいComThread.InitMTA
。ComThread.Release
ワーカー スレッドでこれを行うのを忘れた場合、そのスレッドは自動的にアタッチされ、デタッチされることはありません。
を避けInitSTA
、固執するInitMTA
。COM を使用するスレッドが 1 つしかない場合でも、不安定であることがわかりましInitSTA
た。JACOB の内部マーシャリング メカニズムがどのように機能するかはわかりませんが、有効に見えてもメソッドが呼び出されても何もしない「ゴースト」オブジェクトになってしまいました。
幸いなことに、JACOB ライブラリーのコードを変更する必要はまだありません。
私は自分でこの問題に遭遇しました。initMTAなどをいじった後。簡単な修正を見つけました。Java を起動するときに、コマンド ラインに次の行を追加します。 -Dcom.jacob.autogc=true
これにより、ROT クラスが HashMap の代わりに WeakHashMap を使用するようになり、問題が解決されます。
-Dcom.jacob.debug=true を使用して、多くの有益なデバッグ スピューを表示し、ROT マップのサイズを監視することもできます。
TD2JIRA コンバーターにも同じ問題がありました。最終的には、Jacob ファイルの 1 つにパッチを適用してオブジェクトを解放する必要がありました。その後、すべてがスムーズに進みました。
クライアント 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 クラスは最初はアクセスできませんでした。
アップデート
ジェイコブでリソースを解放する正しい方法は、呼び出すことです
ComThread.InitSTA(); // or ComThread.InitMTA()
...
ComThread.Release();
悪いことは、時にはそれが役に立たないことです。ジェイコブがネイティブ メソッド release() を呼び出したにもかかわらず、メモリ (Java メモリではなく、JVM プロセス メモリ) が制御不能に増加します。