【转】.net框架读书笔记---CLR内存管理\垃圾收集(六)
對(duì)象代齡
代齡是旨在提高垃圾收集器性能的一種機(jī)制。有以下幾點(diǎn):
在托管堆初始化時(shí),其中不包含任何對(duì)象。這時(shí)添加到托管堆中的對(duì)象被稱為第0代對(duì)象。第0代對(duì)象就是新構(gòu)造的對(duì)象,垃圾收集器還沒有對(duì)他們執(zhí)行過任何的檢查,加入新啟動(dòng)一個(gè)應(yīng)用程序托管堆,分配了5個(gè)對(duì)象(A到E),經(jīng)過一段時(shí)間后,對(duì)象C和E將變?yōu)椴豢蛇_(dá)對(duì)象。
當(dāng)CLR初始化時(shí),它會(huì)為第0代對(duì)象選擇一個(gè)閾值,假定為256KB。(實(shí)際可能會(huì)與此不同)當(dāng)分配新對(duì)象導(dǎo)致第0代對(duì)象超過了為其設(shè)定的闕值時(shí),垃圾收集器就必須啟動(dòng)了。假定上面的A到E總共占用了256KB,那么當(dāng)F開始被分配時(shí),垃圾收集器就會(huì)啟。垃圾收集器判定對(duì)象C和E為垃圾,因此會(huì)壓縮對(duì)象D使其鄰接于對(duì)象B。此次垃圾收集器中存活下來的對(duì)象(對(duì)象A,B,D)將被認(rèn)為是第1代對(duì)象。經(jīng)過一輪垃圾收集的檢查加強(qiáng)的存活下來并且光榮的升官加爵。
在第一次垃圾收集執(zhí)行后,0代對(duì)象暫時(shí)空缺。但很快,隨著應(yīng)用程序的運(yùn)行,又有新的對(duì)象被分配而成為第0代對(duì)象。新加入的F到K就變?yōu)榱?代對(duì)象變?yōu)榱藴?zhǔn)炮灰。隨著應(yīng)用程序的運(yùn)行,對(duì)象B(一代長(zhǎng)老),H(0)和J(0)又成為不可達(dá)對(duì)象,它們的內(nèi)存也要在某一點(diǎn)被回收。
現(xiàn)在假設(shè)應(yīng)用程序又試圖分配對(duì)象L,這將在一次使第0代對(duì)象超過它的闕值容量,于是又必須開始執(zhí)行第二次垃圾收集。在這前面,垃圾收集器必須要判定要收集那些代的對(duì)象。垃圾收集器期會(huì)為0代對(duì)象選擇一個(gè)闕值(大約256KB),其實(shí)也會(huì)為第1代對(duì)象選擇一個(gè)闕值容量。假設(shè)第1代對(duì)象的闕值容量為2MB。
當(dāng)?shù)诙卫臻_始執(zhí)行時(shí),它也會(huì)查看第1代對(duì)象占用了多少內(nèi)存,在本例中,由于第一代對(duì)象(A,B,D)占用內(nèi)存遠(yuǎn)少于2MB,所以垃圾收集器只會(huì)去檢查第0代對(duì)象。由于新創(chuàng)建的對(duì)象的生存期比較短,所以第0代對(duì)象成為垃圾對(duì)象的數(shù)量會(huì)比較多,因此對(duì)第0代對(duì)象執(zhí)行垃圾收集將有可能比較多的內(nèi)存,忽略掉第1代對(duì)象提高垃圾收集的速度。
忽略第1代對(duì)象的意義不僅僅在于不對(duì)它們執(zhí)行垃圾收集。實(shí)際上,更重要的是垃圾收集器不用再遍歷整個(gè)托管堆中的對(duì)象了,可以提高垃圾收集器的性能。說忽略代齡較大的對(duì)象的一些內(nèi)部引用,而不是全部?jī)?nèi)部引用是因?yàn)榇g較大的對(duì)象有可能引用一個(gè)新的對(duì)象。為了確保這些代齡較大的對(duì)象中的一些新對(duì)象也能被檢測(cè)到,垃圾收集器使用JIT編譯器內(nèi)部的一種機(jī)制來在對(duì)象的內(nèi)部引用字段改變時(shí)設(shè)置一個(gè)相應(yīng)的為標(biāo)記。這使得垃圾收集器可以知道自從上次垃圾收集執(zhí)行后以來,那些代齡較大的對(duì)象已經(jīng)被應(yīng)用程序所改寫。這樣垃圾收集器只需檢查它們是否引用了第0代對(duì)象就可以了。
生存期比較長(zhǎng)的對(duì)象將趨向于繼續(xù)存活,所以第一代對(duì)象繼續(xù)成為可達(dá)對(duì)象的可能性比較大。所以第一代對(duì)象繼續(xù)成為可達(dá)對(duì)象的可能性比較大。因此垃圾收集器檢查第一代對(duì)象,很有可能找不到很多垃圾,能夠回收的內(nèi)存也就有限,這樣收集第一代很有可能浪費(fèi)大量的時(shí)間。如果垃圾對(duì)象位于第一代,那么它仍然健在。第二次垃圾收集后。托管堆中存在
A--B---D---F--G---I---K(均為一代長(zhǎng)老了)
第0代對(duì)象中的幸存者有升官加爵了變?yōu)?代,因?yàn)槔占鳑]有檢查第一代,B內(nèi)存沒有被收集。雖然已經(jīng)成為不可達(dá)對(duì)象。但是由于沒有經(jīng)歷洗禮,所以沒有升官加爵;
此時(shí)0代為空,新的對(duì)象繼續(xù)加入成為了0代長(zhǎng)老(L到O),過一段時(shí)間,G、L、M又成為不可達(dá)對(duì)象。此時(shí)托管堆如下:
一代A---B---D---F---G---I---K 0代L---M---N---O
此時(shí)1代中堆著N多的不可達(dá)垃圾包括B。
此時(shí)對(duì)象P的加入又是0代超標(biāo)了,繼續(xù)垃圾收集。因?yàn)?代的容量2MB,沒有超標(biāo),繼續(xù)不對(duì)1代收集(B,G為1代中的蛀蟲);本次垃圾收集完畢后,托管堆如下:
一代A---B---D---F---G---I---K---N----O
0代被適時(shí)殺死,一代里面的蛀蟲繼續(xù)增長(zhǎng),沒有控制是不行的,結(jié)果一代的容量達(dá)到了其闕值2MB,此時(shí)應(yīng)用程序分配P到S對(duì)象,這時(shí)0代又滿了。此時(shí)托管堆的分配情況:
一代A---B---D---F---G---I---K---N----O? 0代P----Q----R----S
此時(shí)應(yīng)用程序試圖分配對(duì)象T,當(dāng)然是沒有地方了,0,1代都滿了,需要清理了,這時(shí)發(fā)現(xiàn)一代對(duì)象的內(nèi)存容量已經(jīng)達(dá)到了2MB,然而一代中存在著大量幸存下來的垃圾。本次垃圾收集器是公平的,同時(shí)收集第0代和第1代中所有的垃圾對(duì)象,痛苦,所以的垃圾一掃而光了,此時(shí)托管堆為:
二代D---F---I----N----O? 二代Q-----S(0代空了)
和前面一樣,本次垃圾收集完畢后,幸存下來的將被提升為1代,而一代中存活下來的被榮升為2代了,0代為空了,在產(chǎn)生第二代對(duì)象之前,系統(tǒng)有可能已經(jīng)執(zhí)行了多次垃圾收集,但只有在第一代對(duì)象的內(nèi)存總量達(dá)到其闕值時(shí),垃圾收集器才會(huì)檢查一代對(duì)象,而此時(shí)系統(tǒng)可能已經(jīng)對(duì)0代對(duì)象執(zhí)行了N多次垃圾收集了。
CLR托管堆只支持3個(gè)代齡,0,1,2,CLR初始化時(shí)都會(huì)為其設(shè)置闕值容量(大約為,256KB,2MB,10MB),
CLR垃圾收集器是一個(gè)自調(diào)結(jié)的玩意,他會(huì)根據(jù)對(duì)象的狀態(tài),變?yōu)椴豢蛇_(dá)的頻率自適應(yīng)的調(diào)節(jié)闕值。實(shí)在是高啊。
?
CLR的垃圾收集原理其實(shí)也給人一人生道理,要想活得更長(zhǎng),就需向更高一層走,而要想往更高一層走就要經(jīng)過殘酷的洗禮。剩者為王。
?
- 屠刀總是先指向弱者,因?yàn)閺?qiáng)者數(shù)大根深啊,殺一次得不償失
- 強(qiáng)者擁有更多的資源和更多的容忍
- 再?gòu)?qiáng)也不要超過別人給的限度,否則權(quán)利是人家給的,人家不高興了隨時(shí)可以拿回去
總結(jié)
以上是生活随笔為你收集整理的【转】.net框架读书笔记---CLR内存管理\垃圾收集(六)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 学历低不能办理信用卡吗
- 下一篇: 【转】.net框架读书笔记---CLR内