當前位置:
首頁 > 知識 > .Net陷阱破解:大對象堆碎片化處理

.Net陷阱破解:大對象堆碎片化處理

了解垃圾回收機制對使用.Net很重要。CLR管理兩個獨立的堆,即小對象堆(SOH)和大對象堆(LOH)。本文將重點介紹運行時如何管理大對象堆、大對象堆產生內存碎片的原因以及大對象堆(LOH)內存碎片最小化的方法。

.Net陷阱破解:大對象堆碎片化處理

小對象堆垃圾回收機制

垃圾回收器會適當清理不使用的應用程序。小對象堆和大對象堆的在垃圾回收器中工作方式不同,我們先來了解一下小對象堆的工作方式。

當創建的對象小於85K時存儲在小對象堆中。CLR將小對象堆依據不同時間間隔收集分成三代——第0代、第1代和第2代。小對象通常被分配給第0代,如果它們在GC周期中存活,則被提升為第1代。如果在下一次GC周期中依然存活,就會被提升到第2代。

小對象堆垃圾收集採用壓縮的方法,這意味著當收集到未使用的對象時,GC將活動對象移動到間隙、消除碎片,以確保可用內存連續。當然,壓縮包括開銷——兩個CPU周期和用於複製對象的附加內存。壓縮會在小對象堆上自動執行,這樣就大大降低小對象的成本。

.Net陷阱破解:大對象堆碎片化處理

大對象堆中內存碎片化的形成

但以上壓縮方法由於成本太高,不適用於大對象堆(大於85K)。除此之外,複製和移動大型對象會涉及到垃圾收集器巨大開銷、GC需要的內存是垃圾收集的兩倍、再次移動大對象也會非常耗費時間也是不適用於大對象堆的主要原因。所以大對象堆的垃圾收集不採用壓縮的方法。那大型對象堆中的內存如何回收?

在大對象堆中,GC從不移動大對象,只需在不需要時刪除。在不斷刪除存儲的過程中,大對象堆中逐步存在內存漏洞,這就是所謂的內存碎片化。

雖然GC不對大對象堆進行壓縮,但是會將其中的相鄰空閑塊連在一起,這樣會創造一個更大的空閑塊,並將其作為優化策略添加到空閑列表中。

需要注意的是,GC僅在第2代中從大對象堆中收集未使用的對象。換句話說,在從大對象堆中回收內存之前,GC會先回收駐留在小對象堆中的內存。因此,大對象堆不僅受到內存碎片的影響,而且具有存活時間更長、在不被使用情況下也佔用空間的特性。

在這個過程中,壓縮對象的成本與大小成正比,而且這個成本不低,還會降低性能,所以大對象就被存儲在一個單獨的堆中。

大對象堆保持最小碎片化實踐

上面我們已經了解到大對象堆碎片化產生的原因,下面我們來介紹保持大對象最小碎片化的做法。

.Net陷阱破解:大對象堆碎片化處理

推薦的做法是識別應用程序中的大對象,然後將其分割成較小的對象——也可能會使用一些包裝類(wrapper class)。另一種是重新設計應用程序,在設計過程中避免大對象的使用。還可以定期回收應用程序池。

雖然GC本身不會壓縮大對象堆,但我們可以採用代碼對大對象堆進行壓縮。以下代碼片給出實現過程:

GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;

GC.Collect();

其實在.Net Framework 4.5中管理大對象堆的方式有了許多顯著改進。

運行時通過反覆檢查使用可用內存塊管理大對象堆。在.Net框架的先前版本中,一個內存塊一旦被拒絕作為分配的候選對象,在後續分配中將不再考慮。

第二個改進是,如果你使用的是Server GC模式,運行時均衡應用程序使用中所有邏輯處理器之間的大對象堆分配,在.NET Framework 4.5之前,只有小對象堆分配在整個處理器之間進行了平衡。這些都極大提高了大對象堆內存性能。

.Net陷阱破解:大對象堆碎片化處理

總而言之,垃圾收集器運行時將小對象堆作為優化策略的一部分來消除大對象堆內存漏洞,但是永遠不會因為性能對大型對象堆進行壓縮處理。但如果在x86系統中運行使用許多大對象的程序,可能會遇到OutOfMemory異常,如果在x64系統中運行,可能會有碎片化堆的生成。通過了解垃圾收集機制和大對象堆的複雜性,我們可以採用避免內存碎片化的策略幫助應用程序正常運行。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 IT168企業級 的精彩文章:

互聯網時代的BAT 在人工智慧領域都做了什麼?
在無線技術創新方面 新華三這次贏了
框架將取代編程語言,成為程序編寫的必然選擇?

TAG:IT168企業級 |

您可能感興趣

C++對象的使用:四種對象生存期和作用域、static 用法總結
Secret 資源對象的使用
Python基礎知識——序列對象
Shelve:對象的持久化存儲
Python對象真值判定邏輯粗解與簡明例子
Kotlin 類和對象
利用fastjson反序列化json為對象和對象數組
oc中對指針、對象和%符號的理解
iPhone指紋識別新漏洞!你對象也能解鎖!
static 成員變數、static 成員函數、類/對象的大小
淺析requests庫響應對象的text和content屬性
似曾相識的甲殼蟲?Patta此次的聯名對象竟是…
OpenStack資料庫遠程對象模型
Python面試之可變對象和不可變對象
Python列印對象的全部屬性
簡單定義Python和Scala的類和對象
Google AI用「語義連貫」將對象物逼真地亂入各種場景製作
Python入門基礎之面向對象四:運算符重載
面向不同需求的對象存儲系統對比:Ceph與Swift
一個有趣的利用Equation對象的Remcos RAT變種