2009-06-11 78 views
2

我有一個eclipse插件,它使用Jacob連接到COM組件。但是完全關閉插件之後,.exe文件仍停留在Windows進程中。JACOB沒有正確釋放對象

我使用ComThread.InitMTA(true)進行初始化,並確保SafeRelease()爲我在關閉應用程序之前創建的每個COM對象調用,我最後調用ComThread.Release()

我是否有遺漏某些東西?

回答

4

與TD2JIRA轉換器有同樣的問題。最終不得不修補其中一個Jacob文件來釋放這些對象。之後,一切順利。

在我的客戶端退出的代碼()方法現在看起來是這樣的:

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類是無法訪問的開始,AFAIR。

更新

釋放資源雅各正確的方法是調用

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

壞事是,雖然有時候它並不能幫助。儘管Jacob調用了本地方法release(),但內存(甚至不是Java內存,但是JVM進程內存)卻無法控制地增長。

+0

感謝弗拉基米爾的反饋意見。 我使用了一個測試應用程序,並在測試應用程序關閉後立即關閉.exe。對於雅各布,您的解決方案似乎可行,5分鐘內即可刪除.exe,並且在任務管理器中沒有發現內存使用情況的變化。持續5分鐘的持續時間是否正常?也許是雅各布的問題? – Gorro 2009-06-11 13:38:07

+0

我不得不承認,解決方案是基於直覺的(經過多次嘗試),而且我沒有任何支持或解釋它的知識。 :( – 2009-06-11 15:28:54

5

一些進一步的建議:

  1. 移動調用ComThread.Release()finally塊,否則,如果有異常拋出該線程將保持連接。

  2. 檢查您是否在每個使用COM對象的線程中調用ComThread.InitMTAComThread.Release。如果您忘記在工作線程中執行此操作,那麼該線程將自動連接並永不分離。

  3. 避免InitSTA並堅持InitMTA。即使只有一個線程使用COM,我發現InitSTA是片狀的。我不知道JACOB的內部編組機制是如何工作的,但我最終得到的「鬼」對象似乎是有效的,但在調用它們的方法時什麼也不做。

幸運的是,我從來沒有需要修改JACOB庫中的任何代碼。

6

我自己遇到了這個問題。在和initMTA混淆之後,等等。我發現了一個簡單的解決方法 - 當您啓動Java以下內容添加到您的命令行: -Dcom.jacob.autogc =真

這將導致ROT類使用WeakHashMap中,而不是一個HashMap和解決該問題。

您也可以使用-Dcom.jacob.debug = true來查看大量有用的調試信息並觀察ROT地圖的大小。