欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.NET垃圾回收器(GC)原理淺析

 更新時間:2015年01月15日 08:57:50   投稿:junjie  
這篇文章主要介紹了.NET垃圾回收器(GC)原理淺析,本文先是講解了一些基礎(chǔ)知識如托管堆(Managed Heap)、CPU寄存器(CPU Register)、根(Roots)等,然后講解了垃圾回收的基本原理、算法等,需要的朋友可以參考下

作為.NET進階內(nèi)容的一部分,垃圾回收器(簡稱GC)是必須了解的內(nèi)容。本著“通俗易懂”的原則,本文將解釋CLR中垃圾回收器的工作原理。

基礎(chǔ)知識

托管堆(Managed Heap)

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

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

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

CPU寄存器(CPU Register)

這個是計算機基礎(chǔ)知識,這里復(fù)習一下,有助于對下面“根”概念的理解。

CPU寄存器是CPU自己的”臨時存儲器”,比內(nèi)存的存取還快。按與CPU遠近來分,離得最近的是寄存器,然后緩存(計算機一、二、三級緩存),最后內(nèi)存。

根(Roots)

類中定義的任何靜態(tài)字段,方法的參數(shù),局部變量(僅限引用類型變量)等都是根,另外cpu寄存器中的對象指針也是根。根是CLR在堆之外可以找到的各種入口點。

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

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

垃圾回收的原因

從計算機組成的角度來講,所有的程序都是要駐留在內(nèi)存中運行的。而內(nèi)存是一個限制因素(大小)。除此之外,托管堆也有大小限制。如果托管堆沒有大小限制,那C#的執(zhí)行速度要優(yōu)于c了(托管堆的結(jié)構(gòu)讓它有比c運行時堆更快的對象分配速度)。因為地址空間和存儲的限制因素,托管堆要通過垃圾回收機制,來維持它的正常運作,保證對象的分配,不會“內(nèi)存溢出”。

垃圾回收的基本原理

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

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

標記完成后,進入壓縮階段。在這個階段中,垃圾回收器線性的遍歷堆,以尋找不可達對象的連續(xù)內(nèi)存塊。并把可達對象移動到這里以壓縮堆。這個過程有點類似于磁盤空間的碎片整理。

如上圖所示,綠色框表示可達對象,黃色框為不可達對象。不可達對象清除后,移動可達對象實現(xiàn)內(nèi)存壓縮(變得更緊湊)。

壓縮之后,“指向這些對象的指針”的變量和CPU寄存器現(xiàn)在都會失效,垃圾回收器必須重新訪問所有根,并修改它們來指向?qū)ο蟮男聝?nèi)存位置。這會造成顯著的性能損失。這個損失也是托管堆的主要缺點。

基于以上特點,垃圾回收引發(fā)的回收算法也是一項研究課題。因為如果真等到托管堆滿才開始執(zhí)行垃圾回收,那就真的太“慢”了。

垃圾回收算法 – 分代(Generation)算法

代是CLR垃圾回收器采用的一種機制,它唯一的目的就是提升應(yīng)用程序的性能。分代回收,速度顯然快于回收整個堆。

CLR托管堆支持3代:第0代,第1代,第2代。第0代的空間約為256KB,第1代約為2M,第2代約為10M。新構(gòu)造的對象會被分配到第0代。

如上圖所示,當?shù)?代的空間滿時,垃圾回收器啟動回收,不可達對象(上圖C、E)會被回收,存活的對象被歸為第1代。

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

實際CLR的代回收機制更加“智能”,如果新創(chuàng)建的對象生存周期很短,第0代垃圾也會立刻被垃圾回收器回收(不用等空間分配滿)。另外,如果回收了第0代,發(fā)現(xiàn)還有很多對象“可達”,

并沒有釋放多少內(nèi)存,就會增大第0代的預(yù)算至512KB,回收效果就會轉(zhuǎn)變?yōu)椋豪厥盏拇螖?shù)將減少,但每次都會回收大量的內(nèi)存。如果還沒有釋放多少內(nèi)存,垃圾回收器將執(zhí)行

完全回收(3代),如果還是不夠,則會拋出“內(nèi)存溢出”異常。

也就是說,垃圾回收器會根據(jù)回收內(nèi)存的大小,動態(tài)的調(diào)整每一代的分配空間預(yù)算!達到自動優(yōu)化!

總結(jié)

垃圾回收背后有這樣一個基本的觀念:編程語言(大多數(shù)的)似乎總能訪問無限的內(nèi)存。而開發(fā)者可以一直分配、分配再分配——像魔法一樣,取之不盡用之不竭。

.NET垃圾回收器的基本工作原理是:通過最基本的標記清除原理,清除不可達對象;再像磁盤碎片整理一樣壓縮、整理可用內(nèi)存;最后通過分代算法實現(xiàn)性能最優(yōu)化。

相關(guān)文章

  • WindowsForm移動一個沒有標題欄的窗口的方法

    WindowsForm移動一個沒有標題欄的窗口的方法

    這篇文章主要介紹了WindowsForm移動一個沒有標題欄的窗口的方法,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下
    2020-07-07
  • c#動態(tài)加載卸載DLL的方法

    c#動態(tài)加載卸載DLL的方法

    這篇文章介紹了c#動態(tài)加載卸載DLL的方法,有需要的朋友可以參考一下
    2013-11-11
  • C# 屏蔽由于崩潰彈出的windows異常彈框

    C# 屏蔽由于崩潰彈出的windows異常彈框

    這篇文章主要介紹了C# 屏蔽由于崩潰彈出的windows異常彈框,需要的朋友可以參考下
    2017-08-08
  • C#小知識之有趣的類型靜態(tài)構(gòu)造器

    C#小知識之有趣的類型靜態(tài)構(gòu)造器

    這篇文章主要介紹了C#小知識之有趣的類型靜態(tài)構(gòu)造器,本文直接給分實例代碼,然后分析了C#中的這一個有趣的現(xiàn)象,需要的朋友可以參考下
    2015-04-04
  • C#實現(xiàn)聊天窗體以及抖動

    C#實現(xiàn)聊天窗體以及抖動

    這篇文章主要為大家詳細介紹了C#實現(xiàn)聊天窗體以及抖動,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C#實現(xiàn)功能強大的中國農(nóng)歷日歷操作類

    C#實現(xiàn)功能強大的中國農(nóng)歷日歷操作類

    這篇文章主要介紹了C#實現(xiàn)功能強大的中國農(nóng)歷日歷操作類,實例分析了C#操作時間及字符串的技巧,非常具有實用價值,需要的朋友可以參考下
    2015-03-03
  • C#多線程之線程控制詳解

    C#多線程之線程控制詳解

    這篇文章主要為大家詳細介紹了C#多線程之線程控制的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • C#選擇排序法實例分析

    C#選擇排序法實例分析

    這篇文章主要介紹了C#選擇排序法,實例分析了C#排序算法的實現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-04-04
  • C#使用private font改變PDF文件的字體詳解

    C#使用private font改變PDF文件的字體詳解

    這篇文章主要給大家介紹了關(guān)于C#使用private font改變PDF文件的字體的相關(guān)資料,文中通過示例代碼以及圖片介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-07-07
  • 在Winform和WPF中注冊全局快捷鍵實現(xiàn)思路及代碼

    在Winform和WPF中注冊全局快捷鍵實現(xiàn)思路及代碼

    如果注冊快捷鍵,RegisterHotKey中的fsModifiers參數(shù)為0,即None選項,一些安全軟件會警報,可能因為這樣就可以全局監(jiān)聽鍵盤而造成安全問題,感興趣的你可以參考下本文
    2013-02-02

最新評論