2012-10-25 24 views
6

我需要使用無法修改的外部裝配。假設我使用一個類從組裝像這樣:處理外部裝配導致的內存泄漏

using (ExternalWidget widget = new ExternalWidget()) 
{ 
    widget.DoSomething(); 
} 

每次我把這個代碼,它泄漏非託管內存。 ExternalWidget implements IDisposable並且我已將它包裝在using聲明中,但ExternalWidget未清除其非託管資源。

由於我無權訪問ExternalWidget代碼,因此無法正確解決此問題。有沒有其他方法可以釋放ExternalWidget所使用的內存資源?

+0

創建一個小樣本程序來演示問題並聯系圖書館的作者。 – Henrik

+1

如果您知道內存泄漏的原因,您可能可以使用反射來修復它(我們必須使用舊版本的Infragistics控件庫來執行此操作)。 – sloth

+0

你怎麼知道它沒有清理非託管資源? –

回答

4

如果這是真的非託管內存泄漏,你不能更改代碼,那麼你可以做的事情很少。該框架無法理解,也不能清理該代碼。

在這種情況下的方法是隔離該組件。這意味着訪問會有很多開銷,但沒有其他的事情可以做。

您不能在另一個應用程序域中運行代碼,因爲非託管代碼沒有應用程序域的概念。

這留下了過程級別。我建議在WCF中創建一個服務合約,模仿ExternalWidget以及Shutdown方法的調用。

然後,您將通過命名管道綁定創建一個會公開此合同的EXE(通過會話,因此您可以保持ExternalWidget實例,除非每個調用都是無狀態的)。

作爲EXE的一個參數,它需要一個唯一的標識符(使用Guid)並將其作爲設置WCF服務端點的一部分。

然後,您會撥打電話,當您完成ExternalWidget的實例時,請致電Shutdown; EXE會知道停止等待,然後進程將退出,操作系統將回收內存。

當然,有一個巨大的的開銷在這裏,所以,如果你發現你正在做大量話費,不需要一個新的進程的每一組的電話,你可以展開想法變成服務,它會統計呼叫,然後回收流程(服務將仍然需要掏空,否則它將耗盡資源)。

需要注意的是,如果這原來是一個管理內存問題,那麼你可以隨時旋轉了一個新的應用領域(如需要編組結果來回)那裏運行你的代碼,然後鬆開應用領域。