C#--垃圾回收

垃圾回收.png

? 在C#中,內(nèi)存的是由CLR進行管理,而在C\C++中內(nèi)存是由程序員手動管理。這樣的弊端就很明顯:1.忘記釋放不需要的內(nèi)存毯焕,造成內(nèi)存泄露;2.嘗試訪問已釋放的內(nèi)存磺樱,造成內(nèi)存破壞纳猫,程序錯誤,進而造成安全漏洞竹捉。而C#中由系統(tǒng)管理芜辕,不需要的內(nèi)存,由CLR進行清理块差。清理不需要的內(nèi)存侵续,就是C#中的垃圾回收。

1.從托管堆分配資源

? 在CLR中,所有對象都是從托管堆中分配憨闰,在進程初始化時状蜗,CLR會為此進程劃分一份地址空間區(qū)域作為托管堆,并且CLR中維護一個指針NextObjPtr(初始化時鹉动,為此空間區(qū)域的基地址)诗舰,它指向下一個對象在托管堆中所要分配的地址。當此托管堆區(qū)域被非垃圾對象填滿時训裆,系統(tǒng)將分配更多地址空間眶根。32位系統(tǒng)最多分配1.5GB,64位系統(tǒng)最多分配8TB边琉。

? C#在初始化一個對象時有以下操作:

  1. 計算類型字段的所需字節(jié)數(shù);

  2. 加上對象的開銷所需字節(jié)數(shù)(類型對象指針,和同步塊索引);

  3. CLR檢查區(qū)域是否有足夠的字節(jié)數(shù)分配給新對象;

? 在托管堆中一般連續(xù)分配的對象都有較強的聯(lián)系属百,所以連續(xù)的內(nèi)存地址會引用“局部化”獲得性能的提升,這樣使進程工作集會非常小变姨,應用程序只需要使用很少的內(nèi)存族扰,從而 提供速度。以上有個前提是內(nèi)存無限,現(xiàn)實中渔呵,CLR通過“垃圾回收”怒竿,去清理不需要的對象,來盡可能增加內(nèi)存使用效率扩氢。

2.垃圾回收算法

? 當程序調(diào)用new操作符時耕驰,沒有足夠的內(nèi)存空間來分配是,CLR就執(zhí)行垃圾回收录豺。

  1. 引用計數(shù)垃圾回收器算法:(在Microsoft的“組件對象模型”用的就是此算法)這種算法朦肘,在程序中對上的每個對象都維護著一個內(nèi)存字段來統(tǒng)計程序有多少“部分”正在使用對象。隨著每一“部分”到達代碼中某個不需要對象的地方双饥,就遞減對象的計數(shù)字段媒抠。計數(shù)字段變成0,對象就可以從內(nèi)存中刪除了咏花。這有個弊端趴生,在GUI應用程序中,窗口將容納對子UI元素的引用昏翰,而子UI元素將容納對父窗口的引用苍匆。這種引用會組織兩個對象的計數(shù)器達到0,所以這兩個對象永遠不會刪除矩父。

這種算法因為存在問題,所以CLR使用另一種“引用跟蹤算法”排霉。

  1. 引用跟蹤算法:此算法只關(guān)心引用類型的變量窍株,只有這種變量才會引用堆上的對象,這種變量稱為攻柠。

    (1)CLR開始執(zhí)行GC時球订,首先暫停進程中的所有線程(防止線程在檢查期間訪問對象并更改狀態(tài));

    (2)CLR進入GC的標記階段瑰钮,CLR遍歷堆中的所有對象冒滩,將同步塊索引字段中的一位設為0(0表示對象應刪除);

    (3)CLR檢查所有活動根浪谴,檢查他們引用了哪些對象(這就是引用跟蹤)开睡。如果根引用了堆上的對象,CLR就會標記被引用的對象苟耻,將該對象的同步塊索引中的位設為1篇恒,一個對象被標記后,CLR會檢查對象中的根凶杖,并標記他們引用的對象胁艰,如果發(fā)現(xiàn)對象已經(jīng)被標記,則不重新檢查對象的字段。(這就避免了引用計數(shù)垃圾回收器算法中的循環(huán)引用而產(chǎn)生的死循環(huán)腾么,導致對象無法被刪除)奈梳。

    (4)檢查完畢后,同步塊索引中標記為0的被刪除解虱,標記為1的保留攘须。

    (5)執(zhí)行GC中的壓縮階段,這個階段將保留的對象所占的內(nèi)存地址進行改變饭寺,使他們占用連續(xù)的內(nèi)存地址(好處:1.使保留的對象恢復引用“局部化”阻课,減小程序工作集,提升訪問這些對象的性能艰匙;2.使剩下的可用空間也是連續(xù)的限煞;3. 壓縮空間,解決堆中的空間碎片化問題)员凝。

    垃圾回收示例.png

3.代:提升性能

? CLR中的GC是基于代的垃圾回收器

  1. 對象越新署驻,生存周期越短;
  2. 對象越老,生存周期越長健霹;
  3. 回收堆的一部分旺上,速度快于回收整個堆。

其工作原理:

  1. 當程序首次運行時糖埋,新初始化的對象都為第0代對象宣吱;
  2. 當?shù)?代對象占用的空間達到CLR中的預算容量時(CLR初始化時,會為每代的對象設置一個預存容量)瞳别,GC開始執(zhí)行征候,利用引用跟蹤算法,將不可達的對象清理祟敛,而未清理的對象成為第1代對象疤坝。所以每次GC后,第0代就沒有對象了馆铁;
  3. 然后新創(chuàng)建的對象則會分配到0代中跑揉,循環(huán)上面的清理過程。
  4. 當?shù)?代對象占用的內(nèi)存空間達到預設容量時埠巨,GC就是利用引用跟蹤算法历谍,清理第1代對象,而未清理的對象則會升為第2代對象(第2代對象為GC中的最高代對象辣垒,GC中只包含3代對象)扮饶,在第1代對象沒有達到預設容量時,則不會管第1代中的對象乍构,就算在執(zhí)行GC時甜无,第1代中含有不可達對象扛点,也不會在此時清理。
  5. 當然CLR中對每代對象的預設對象不是恒定不變的岂丘,比如:當每次回收第0代對象后陵究,所存活的對象很少,則會減少第0代對象的內(nèi)存空間預設容量奥帘;反之铜邮,每次回收第0代對象后,所存的對象很多寨蹋,則會增加第0代對象的內(nèi)存空間預設容量松蒜。
第一次垃圾回收.png

一個新初始化的堆,其中包含了一些對象, 這些對象都是0代, 有顏色的是可達對象, 無顏色的是不可達的.

第一次垃圾回收后.png

經(jīng)過一次垃圾回收, 第0代中的可達對象升級為第1代 ; 其他的被清除, 此時第0代沒有對象

垃圾回收2.png

第0代分配了新對象,第1代有垃圾產(chǎn)生(第1代內(nèi)存未達到預設值)

垃圾回收3.png

第2次回收后,第0代的可達對象升級為第1代, 之前第1代中的垃圾并沒有被清理

垃圾回收4.png

第1代產(chǎn)生更多垃圾, 第0代有新增對象

垃圾回收5.png

第3次回收, 因為第1代已達到預設值, 則將第1代可達對象升級為第2代, 第0代可達對象升級為第1代.(垃圾回收中 最高為第2代)

4.垃圾回收觸發(fā)條件

  1. CLR在檢測到第0代超過預算時;

  2. 代碼顯示調(diào)用system.GC的靜態(tài)Collect方法;

  3. Windows報告低內(nèi)存情況;

  4. CLR正在卸載AppDomain;

  5. CLR正在關(guān)閉.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市已旧,隨后出現(xiàn)的幾起案子秸苗,更是在濱河造成了極大的恐慌,老刑警劉巖运褪,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惊楼,死亡現(xiàn)場離奇詭異,居然都是意外死亡秸讹,警方通過查閱死者的電腦和手機檀咙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來璃诀,“玉大人弧可,你說我怎么就攤上這事×踊叮” “怎么了棕诵?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長氧秘。 經(jīng)常有香客問我年鸳,道長趴久,這世上最難降的妖魔是什么丸相? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮彼棍,結(jié)果婚禮上灭忠,老公的妹妹穿的比我還像新娘。我一直安慰自己座硕,他們只是感情好弛作,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著华匾,像睡著了一般映琳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天萨西,我揣著相機與錄音有鹿,去河邊找鬼。 笑死谎脯,一個胖子當著我的面吹牛葱跋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播源梭,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼娱俺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了废麻?” 一聲冷哼從身側(cè)響起荠卷,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎脑溢,沒想到半個月后僵朗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡屑彻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年验庙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片社牲。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡粪薛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出搏恤,到底是詐尸還是另有隱情违寿,我是刑警寧澤,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布熟空,位于F島的核電站藤巢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏息罗。R本人自食惡果不足惜掂咒,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望迈喉。 院中可真熱鬧绍刮,春花似錦、人聲如沸挨摸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽得运。三九已至膝蜈,卻和暖如春锅移,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背饱搏。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工帆啃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人窍帝。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓努潘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親坤学。 傳聞我的和親對象是個殘疾皇子疯坤,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容