解析.NET記憶體回收(GC)原理

來源:互聯網
上載者:User

作為.NET進階內容的一部分,記憶體回收行程(簡稱GC)是必須瞭解的內容。本著“通俗易懂”的原則,本文將解釋CLR中記憶體回收行程的工作原理。

基礎知識

託管堆(Managed Heap)

先來看MSDN的解釋:初始化新進程時,運行時會為進程保留一個連續的地址空間地區。這個保留的地址空間被稱為託管堆。

“託管堆也是堆”,為什麼這樣說呢?這麼說是希望大家不要被“術語”迷惑,這個知識點的前提是“實值型別和參考型別的區別”。這裡假設讀者已經知道“實值型別儲存在棧中,參考型別儲存在堆中。(參考型別的引用儲存在棧中)”這一重要概念。所以,根據這個理論,除實值型別外,CLR要求所有資源都從託管堆分配。

託管堆維護著一個指標,這裡命名為NextObjPtr,它指向下一個對象在堆中的分配位置。

CPU寄存器(CPU Register)

這個是電腦基礎知識,這裡複習一下,有助於對下面“根”概念的理解。

CPU寄存器是CPU自己的”臨時儲存空間”,比記憶體的存取還快。按與CPU遠近來分,離得最近的是寄存器,然後緩衝(電腦一、二、三級緩衝),最後記憶體。

根(Roots)

類中定義的任何靜態欄位,方法的參數,局部變數(僅限參考型別變數)等都是根,另外cpu寄存器中的對象指標也是根。根是CLR在堆之外可以找到的各種進入點。

對象可達與不可達(Objects reachable and unreachable)

如果一個根引用了堆中的一個對象,則該對象為“可達”,否則即是“不可達”。

記憶體回收的原因

從電腦群組成的角度來講,所有的程式都是要駐留在記憶體中啟動並執行。而記憶體是一個限制因素(大小)。除此之外,託管堆也有大小限制。如果託管堆沒有大小限制,那C#的執行速度要優於c了(託管堆的結構讓它有比c運行時堆更快的對象分配速度)。因為地址空間和儲存的限制因素,託管堆要通過記憶體回收機制,來維持它的正常運作,保證對象的分配,不會“記憶體溢出”。

記憶體回收的基本原理

回收分為兩個階段: 標記 –> 壓縮

標記的過程,其實就是判斷對象是否可達的過程。當所有的根都檢查完畢後,堆中將包含可達(已標記)與不可達(未標記)對象。

標記完成後,進入壓縮階段。在這個階段中,記憶體回收行程線性遍曆堆,以尋找不可達對象的連續記憶體塊。並把可達對象移動到這裡以壓縮堆。這個過程有點類似於磁碟空間的磁碟重組。

如所示,綠色框表示可達對象,黃色框為不可達對象。不可達對象清除後,移動可達對象實現記憶體壓縮(變得更緊湊)。

壓縮之後,“指向這些對象的指標”的變數和CPU寄存器現在都會失效,記憶體回收行程必須重新訪問所有根,並修改它們來指向對象的新記憶體位置。這會造成顯著的效能損失。這個損失也是託管堆的主要缺點。

基於以上特點,記憶體回收引發的回收演算法也是一項研究課題。因為如果真等到託管堆滿才開始執行記憶體回收,那就真的太“慢”了。

記憶體回收演算法 – 分代(Generation)演算法

代是CLR記憶體回收行程採用的一種機制,它唯一的目的就是提升應用程式的效能。分代回收,速度顯然快於回收整個堆。

CLR託管堆支援3代:第0代,第1代,第2代。第0代的空間約為256KB,第1代約為2M,第2代約為10M。新構造的對象會被分配到第0代,

如所示,當第0代的空間滿時,記憶體回收行程啟動回收,不可達對象(C、E)會被回收,存活的對象被歸為第1代。

當第0代空間已滿,第1代也開始有很多不可達對象以至空間將滿時,這時兩代垃圾都將被回收。存活下來的對象(可達對象),第0代升為第1代,第1代升為第2代。

實際CLR的代回收機制更加“智能”,如果新建立的對象生存周期很短,第0代垃圾也會立刻被記憶體回收行程回收(不用等空間分配滿)。另外,如果回收了第0代,發現還有很多個物件“可達”,

並沒有釋放多少記憶體,就會增大第0代的預算至512KB,回收效果就會轉變為:記憶體回收的次數將減少,但每次都會回收大量的記憶體。如果還沒有釋放多少記憶體,記憶體回收行程將執行

完全回收(3代),如果還是不夠,則會拋出“記憶體溢出”異常。

也就是說,記憶體回收行程會根據回收記憶體的大小,動態調整每一代的分配空間預算!達到自動最佳化!

總結

記憶體回收背後有這樣一個基本的觀念:程式設計語言(大多數的)似乎總能訪問無限的記憶體。而開發人員可以一直分配、分配再分配——像魔法一樣,取之不盡用之不竭。

.NET記憶體回收行程的基本工作原理是:通過最基本的標記清除原理,清除不可達對象;再像磁碟磁碟重組一樣壓縮、整理可用記憶體;最後通過分代演算法實現效能最佳化。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.