1

好的,只是要清楚,我知道任務管理器從來不是監視程序內存消耗的好方法。現在我已經清空了空氣.......NET 4.0中的GC不會影響任務管理器中的工作集

我已經使用了SciTech的.Net內存分析器一段時間了,但幾乎完全在我們的應用的.Net 3.5版本中。通常,我會運行一個操作,收集基線快照,再次運行該操作,並收集比較快照並從那裏發起泄漏。一般來說,任務管理器會模仿內存的上升和下降(在一定的準確度範圍內和一段時間內)。

在我們的.net 4.0應用程序中,我們的測試部門在執行一組操作時報告了內存(我將稱其爲操作A)。在剖析器中,我會看到活躍字節的巨大變化(通常表示泄漏)。如果我立即收集另一個快照,則回收內存(無論我等待收集初始比較快照多長時間)。我想終結可能會被卡住,所以我手動注入以下呼叫:

GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 

當我這樣做,我不認爲在探查初始泄漏,但在任務管理器中我的工作集仍可笑的高(操作A涉及加載圖像)。我認爲這個問題可能是一個堅持不了的終結者(當探查者收集它的快照時,SciTech能夠做出一些巫術魔法),但是在我使用WinDbg和MDbg的所有時間裏,我找不到任何暗示終結者被卡住了。如果我只是讓我的應用坐幾個小時,工作集中的內存永遠不會減少。但是,如果我繼續進行其他操作,內存將在隨機點大幅下降。我知道GC在CLR 4.0中有了很大的改變,但它是否會影響操作系統如何分配內存?我的電腦有12 GB內存,所以當我運行我的應用程序並增加我的內存使用量時,我仍然有免費的TONS,所以我推測它只是不在意減少它已分配的內容(如任務管理器),即使內存已被「收集」。當我在1GB RAM的機器上運行這個相同的操作時,我從來沒有發現內存不足的例外情況,這表明我真的沒有泄漏內存(Profiler也建議這麼做)。

我關心任務管理器顯示的唯一原因是因爲這是我們的客戶如何監控我們的內存使用情況。如果GC發生改變會影響到這一點,我只是希望能夠向他們展示說它是微軟的錯誤,而不是我們的文檔:)

在我的盡職調查中,我搜查了一堆其他SO線程的答案,但我發現的所有文章都是關於世代清理的併發性和其他不相關的,但有用的事實。

回答

0

您不能指望立即反映在進程內存中的託管堆的使用發生更改。 CLR本質上充當了代表應用程序的內存管理器,因此它根據需要分配和釋放段。由於分配和釋放細分是一項昂貴的操作,因此CLR會嘗試優化此操作。它通常不會立即釋放一個空白段,因爲它可能用於服務新的託管分配。如果你想監視託管的內存使用情況,你應該依靠.NET特定的計數器。

+0

感謝您的回覆。我理解並同意你的回答(並且着重試圖說服別人,任務管理器從來不是衡量內存使用情況的準確方法)。無論如何,客戶仍然在使用它。我的觀點是,在3.5和之前的CLR中,我至少會看到任務管理器顯示的可預測的波動。現在,內存會在預期時增加,但不會減少(除非我執行其他隨機操作,否則內存不會減少)。我不是說這意味着我有泄漏。我只是想知道是否CLR 4中的某些內容會影響到這一點。 – Devin

+0

任務管理器適用於進程內存,但託管內存只是整個進程內存的一部分,CLR可以自由地執行任何所需操作,以優化進程分配/釋放託管堆所需內存的方式。 –

+0

再說一次,好點,但我的問題是CLR 3.5和4.0之間是否會改變這種看法。我很想向客戶解釋託管內存的細微差別,但他們似乎並不在乎。但是,他們確實付錢給我們,我需要確保他們很高興:) – Devin