我嘗試過的大多數.NET內存分析器都允許您拍攝內存快照。是否有一個.Net內存分析器將跟蹤大對象堆上的所有分配?
但是,我正在嘗試診斷一個問題,即最終導致分配給.NET的大量內存被ANTS分析器指示爲「空閒」。 (我已經證實了這個問題與其他分析器如Mem Profiler和CLR分析器
ANTS顯示我有大量的內存碎片(100%的可用內存與150MB作爲最大的塊)。堆中所有對象的大小爲180MB,我有553 MB分配給.NET,152分配給「非託管」。
但是,大對象堆(LOH)的大小僅爲175kb。我沒有分配任何最終在LOH上的對象永久存在。
因此,我的問題,一些沿線的人,我懷疑我以某種方式分配大對象(超過85k限制f或LOH),然後處理它們。我正在從數據庫(Oracle,Sql Server)讀取大量數據(估計在這裏以幾MB爲單位),將這些數據拷貝到內存中的對象數組,並將數據處理成索引(數組,字典等)以便於搜索/過濾/處理。
我的猜測是,數據讀取器臨時分配大量空間。但是,我沒有一個好方法來暫停程序並拍攝內存快照。
我想是一個跟蹤上LOH分配的每個對象的,所以我可以找出是什麼原因造成的LOH碎片和過度使用的內存(內存不返回到操作系統分析器,所以它看起來像我的進程正在花費1GB的內存來存儲200MB的分配對象。)我猜測內存不會被返回,因爲LOH沒有壓縮,所以我在所有這些內存中都卡住了我的進程,這可能是幾周(它作爲一個Windows服務運行)。
編輯:我的問題是,我的.NET應用程序正在使用大量的內存,我無法跟蹤。
編輯1:我已經使用了Visual Studio內存分析器。雖然它告訴我所有實例化的對象,總共有多少字節等,並不是給了我一個提示,告訴我爲什麼最終會獲得如此多的空閒內存。我唯一的提示/線索是ANTS告訴我的:「內存碎片限制了可分配對象的大小。」而且我有很多未使用的內存分配給.NET。
編輯2:更多配置文件顯示我有一些在LOH上分配的短期大對象。但是,分配給LOH的總金額不會超過3到4 MB。但是,在這段時間內,私人字節會穿過屋頂,翻倍和三倍,而實際分配的對象(在所有堆中)的大小隻會略微增加。例如,所有堆中的字節都是115MB,但是我的專用字節超過了512MB。
ANTS清楚地告訴我,我遇到內存碎片問題。原來我正在LOH上製造短暫的物體。但是,這些對象永遠不會超過3或4 MB。所以這些短暫的大型物體(似乎?)正在將LOH分離出來。
迴應Eric Lippert和迪士尼樂園停車場比喻(這很棒)。
這就像有人在現場停了幾分鐘,然後離開。然後保留該地點(沒有其他人可以在那裏停車),直到我重新停車!
我第一次開始調查這個時,Visual Studio警告我的內存使用情況,並建議切換到64位。 (我忘記了警告號碼,快速谷歌沒有找到它)。所以切換到x64可以緩解眼前的問題,但不能解決潛在的問題。
這就像我有一個停車場爲1000輛,但我把100輛汽車在這之後,我的泊車員尖叫,它的全...
幸運的是,我有一個巨大的VMware集羣在我的處置和理解管理員。我已經分配了8個CPU和8GB內存。所以就問題而言,我可以處理它,我只是在投入資源。另外,(正如我上面所說的)我切換到64位,因爲Visual Studio不停地嘮叨我,但我想知道它在LOH上分配了什麼,看看我是否用這種方式緩解了這種堆碎片一些小代碼的變化。也許愚蠢的差事,因爲我可以投入資源。
應用程序運行良好,偶爾出現GC暫停,速度很快。但大多數情況下,我可以忍受這種情況,我只想知道對象是什麼造成的。我的懷疑是一些短命的字典,我還沒有查到。
EDIT3:http://msdn.microsoft.com/en-us/magazine/cc188781.aspx
ObjectAllocatedByClass不跟蹤大對象 堆的分配,但ObjectAllocated一樣。通過比較 這兩者的通知,一個有進取精神的靈魂應該能夠找出與正常的託管堆相對的大對象堆中的內容 。
所以它看起來像這個可以完成。然而,我的C++技能是一種生鏽的方式來挖掘這個(如果我有更多的時間,也許在將來的某個時候)。我希望分析器能夠提供這種開箱即用的功能。
您的應用程序是否使用字符串interning? – 2012-03-28 16:39:48
那麼具體是什麼*問題*?是虛擬內存不足,還是工作集太大,而且你打亂了頁面文件?或者是什麼? – 2012-03-28 16:40:39
當你的LOH只有175kb時,碎片並不是什麼大問題。 – 2012-03-28 16:55:32