我對我正在處理的某些代碼有不尋常的要求。我使用不可靠的第三方庫進行條碼掃描(運行太多次後停止工作)。爲了解決這個問題,我決定在單獨的AppDomain中完成這項工作,然後在完成時卸載AppDomain。這是我做的一個簡單,但準確,圖片:在AppDomain中加載代碼時令人討厭的內存泄露
string domainID = Guid.NewGuid().ToString();
AppDomainSetup setup = new AppDomainSetup();
AppDomain domain = AppDomain.CreateDomain(domainID, null, setup);
string result = null;
try
{
domain.SetData("stream", stream);
domain.DoCallBack(ScanningContext.DoWork);
result = domain.GetData("result") as string;
}
finally
{
AppDomain.Unload(domain);
}
return result;
public static void DoWork()
{
Stream s = AppDomain.CurrentDomain.GetData("stream") as Stream;
ObjectHandle handle = AppDomain.CurrentDomain.CreateInstance("Scanning",
"Scanner");
Scanning.Scanner scanner = (Scanning.Scanner)handle.Unwrap();
Scanning.Result[] results = scanner.Scan(s);
AppDomain.CurrentDomain.SetData("result", results[0].Text);
}
「掃描儀」是圖書館週圍的包裝類我使用。它位於「掃描」程序集中;一個單獨的項目就是爲了這個目的。
ScanningContext.DoWork是一個靜態方法,位於我的服務的程序集中。
這個方法的問題是有一個內存泄漏的地方。內存不斷增長和增長(當然這個代碼被調用了)直到OutOfMemoryExceptions被拋出。
我找不到泄漏的地方。我的所有流都正在處理中。我所有的字節數組都被清零。我正在清單,過去一切爲我工作的東西。我大概有90%的人相信漏洞與這個AppDomain的東西有關。這是我第一次使用它,所以我可能做錯了什麼。
我打開除AppDomains之外的另一種方法。我確實需要從「掃描儀」類返回結果的能力,因此產生過程不是一種選擇。
你說你至少可以運行第三方代碼幾次。那麼你可以通過檢查是否存在漏洞,使用應用程序域來排除最後10%的不確定性嗎? – 2012-02-07 14:13:40
刪除掃描器調用代碼,返回一個固定的結果,並檢查內存是否仍然存在泄漏,然後是其appDomain問題,否則其第三方庫問題。 – 2012-02-07 14:21:09
舊方法消耗大量內存,大約25萬k它現在,所以它的內存使用並不好。然而,它並沒有像我的新方法所做的那樣耗盡內存。因此,要回答你的問題,不,我不能排除其他10%,我不得不重寫一些代碼來使用AppDomain,以便當時可以引入泄漏。 – Matthew 2012-02-07 14:21:20