我有任何地方從10-150長的生活類對象調用使用HttpClient執行簡單的HTTPS API調用的方法。一個PUT調用示例:HttpClientHandler/HttpClient內存泄漏
using (HttpClientHandler handler = new HttpClientHandler())
{
handler.UseCookies = true;
handler.CookieContainer = _Cookies;
using (HttpClient client = new HttpClient(handler, true))
{
client.Timeout = new TimeSpan(0, 0, (int)(SettingsData.Values.ProxyTimeout * 1.5));
client.DefaultRequestHeaders.TryAddWithoutValidation("User-Agent", Statics.UserAgent);
try
{
using (StringContent sData = new StringContent(data, Encoding.UTF8, contentType))
using (HttpResponseMessage response = await client.PutAsync(url, sData))
{
using (var content = response.Content)
{
ret = await content.ReadAsStringAsync();
}
}
}
catch (ThreadAbortException)
{
throw;
}
catch (Exception ex)
{
LastErrorText = ex.Message;
}
}
}
2-3小時後運行這些方法,其中包括通過using
陳述妥善處置,該計劃已穆斯特1GB的內存,1.5GB,並最終以各種崩潰的內存不足錯誤。很多時候,連接都是通過不可靠的代理服務器進行的,因此連接可能無法按預期完成(超時和其他錯誤很常見)。
.NET內存事件探查器指出HttpClientHandler
是這裏的主要問題,指出它具有'直接代表根'的廢棄實例(紅色感嘆號)和'已處理但仍未GCed的實例'(黃色感嘆號)。探查器指示的代表已根據AsyncCallback
s,源自HttpWebRequest。
它也可能與RemoteCertValidationCallback
有關,它與HTTPS證書驗證有關,因爲TlsStream
是「Disposed but not GCed」根目錄下的一個對象。
考慮到這一切 - 我如何更正確地使用HttpClient並避免這些內存問題?我應該每小時強制一次GC.Collect()
嗎?我知道這被認爲是不好的做法,但我不知道如何回收這個不太適合處理的內存,並且對於這些短期對象來說更好的使用模式對我來說並不明顯,因爲它似乎成爲.NET對象本身的一個缺陷。
UPDATE 強制GC.Collect()
沒有效果。
進程的託管字節總數最多保持20-30 MB左右,而進程整體內存(在任務管理器中)持續攀升,表明存在非託管內存泄漏。因此,這種使用模式正在創建一個非託管內存泄漏。
我已經嘗試創建HttpClient和HttpClientHandler的每個建議的類級別的實例,但是這沒有可觀的效果。即使我將它們設置爲課程級別,由於代理設置通常需要更改,因此它們仍會重新創建並很少重複使用。一旦請求被啓動,HttpClientHandler不允許修改代理設置或任何屬性,所以我不斷地重新創建處理程序,就像最初對獨立的using
聲明所做的那樣。
HttpClienthandler仍然與「直接委託根」處置爲AsyncCallback - > HttpWebRequest。我開始懷疑,也許HttpClient不是專爲快速請求和短期生活對象而設計的。沒有盡頭,希望有人建議使用HttpClientHandler可行。
存儲器剖析鏡頭:
你爲什麼要在每次調用中放置'HttpClientHandler'和'HttpClient'? 'HttpClient'應該是整個應用程序中的一個長壽命對象(因此,'HttpClientHandler'也應該是這樣的,這樣,你只需要生成一個實例。 –
我剪掉了代碼中不重要的部分,但頭部根據請求而波動,並且代理會根據連接成功/失敗而改變,HttpClientHandler對象的大量維護都會發生,因此我認爲每次只重新創建一次會比較簡單,但它仍然不能滿足問題爲什麼這些對象不能重複創建而不會重複創建 – user1111380
如果確實嘗試了GC.collect(),您是否看到正在收集這些TlsStream對象? – zaitsman