一個(gè)Java對(duì)象的回憶錄:垃圾回收
對(duì)象的誕生
“你醒啦!”,迷迷糊糊中聽到一個(gè)聲音,我睜開了眼睛,發(fā)現(xiàn)一個(gè)小伙伴正看著我。
“這里是哪里,你是誰啊?”
“這里是堆區(qū),我是一個(gè)Ajax對(duì)象,叫我小A吧”
我慢慢坐了起來,舉目四望,這里有好多形形色色的對(duì)象居住在這里,遠(yuǎn)處還有好多的線程在各自忙碌著,好一副熱鬧的景象!
“你好,我才剛醒,我還不知道我是什么對(duì)象呢”
“這個(gè)簡(jiǎn)單,讓我看看哈~~哦,原來你是一個(gè)APIController對(duì)象啊”,小A摸了摸我的頭。
“你怎么知道的?”
“你的頭上這里有個(gè)64bit的Klass指針,喏,順著這個(gè)方向看過去,那里記錄了你所屬的類信息,你看,那里寫著APIController呢“
聽他這么一說,我這才注意到我的頭上有兩個(gè)64bit的字段。
“唉,小A,旁邊這個(gè)64bit的數(shù)字又是裝的什么內(nèi)容呢?”
“那個(gè)叫MarkWord,是咱們Java對(duì)象的門面,里面的信息可重要了,你可要保管好了,這里面有。。。”
Minor GC
突然,不知從哪里傳來一串警報(bào)聲,隨后聽到廣播:“各線程注意,請(qǐng)進(jìn)入安全點(diǎn)等待,各分區(qū)注意,啟動(dòng)一次Minor GC”
聽到廣播的我莫名的緊張起來。
不知怎么回事,遠(yuǎn)處忙碌的線程們都仿佛被施了定身法一般,都停下了手頭的活。只有少數(shù)幾個(gè)還在活動(dòng),這幾個(gè)線程大叔看上去跟他們有些不一樣,其中有幾個(gè)朝我們這邊走了過來。
“這是要干什么啊?”我向小A打聽情況。
“我也不知道,我也比你先出生沒多久,這情況我也是第一次見到”,小A好像也有一點(diǎn)慌張。
沒過多久,來了一個(gè)兇巴巴的管理員線程,拿著喇叭吼著:“Eden區(qū)的對(duì)象們聽著,念到名字的站起來”
說完,便開始一個(gè)個(gè)點(diǎn)名,心里一陣忐忑,怕被叫到,又怕不被叫到。
念了很久,終于聽到了小A和我的名字,我倆戰(zhàn)戰(zhàn)兢兢的站了起來。
沒多久就念完了,我一瞅,站起來的是少數(shù)啊,心里有點(diǎn)不好的預(yù)感。
“念到名字的跟我來,其他的交給我的助手處理”,說完大家跟著他開始移動(dòng)。
在走的路上,碰上了另外一支隊(duì)伍,和我們匯合了。
“唉,兄弟,怎么稱呼,你們哪個(gè)單位的?”小A熱情的上去和一個(gè)對(duì)象攀談了起來。
“叫我小B吧,我們這波是Survivor From區(qū)的,你們Eden區(qū)來的吧,我半小時(shí)前還在你們那兒待過呢”,這個(gè)自稱是小B的也很隨和。
“小B哥您好,咱們這是要去哪里啊?”我也上前搭了句話。
“前面是Survivor To區(qū)”
“咱們是怎么被挑出來的?”
“這里的管理員會(huì)通過一種叫GC Roots的對(duì)象,順藤摸瓜,找出所有還有引用關(guān)系的對(duì)象,咱們就是幸存者,說明咱們還有價(jià)值”
“那留下的對(duì)象怎么辦?”
“他們的命運(yùn)多半懸了,因?yàn)闆]有別的對(duì)象引用他們了,需要把他們清理掉,騰出空間來”
我似懂非懂,一邊走一邊擔(dān)心著,很快我們就到了傳說中的Survivor To區(qū),管理員安排我們都坐下,“這里好小啊”
“那可不,比起你原來的Eden區(qū),這里只有八分之一大小”,我一回頭,剛才路上碰到的小B居然就在我和小A的旁邊,巧了不是。
“唉,小B哥,咱們這么折騰一圈是在做什么啊?”
“這叫做垃圾回收GC,你們開始待那地方叫Eden區(qū),對(duì)象出生的地方都在那里。咱們所在的地方是一個(gè)叫Java Virtual Machine的世界,程序員只管創(chuàng)建對(duì)象,不管釋放,這對(duì)象越來越多,Eden區(qū)放不下了,自然就要騰出空間來了。”
我和小A都點(diǎn)了點(diǎn)頭,心里慶幸躲過一劫,抬頭望去,不知什么時(shí)候,那些定住的線程們又開始忙活起來了。
“還沒恭喜你們呢,長(zhǎng)大一歲了”,小B拍了拍我倆的肩膀,我倆面面相覷,滿臉問號(hào)。
“這是從何說起呢?”,小A先開口了。
“你們頭上的MarkWord第3-6位記錄的就是你們的年齡,經(jīng)過一次GC就長(zhǎng)大一歲了!”
我倆互相看了看,又看了看小B的GC年齡位置,居然已經(jīng)15歲了。
“小B哥,難怪你見多識(shí)廣,都一把年紀(jì)了呀。咦,這表示GC年紀(jì)的只有4位,最大只能表示到15,等會(huì)兒要是再來一次GC,這不要裝不下了嗎?”,看著小B的腦袋,我陷入了思考。
“再來一次GC我要是還能幸存,我就要進(jìn)入老年代區(qū)域了,就不能陪你們玩兒了”,小B看著我們眨了眨眼睛。
“老年代,那是什么地方,我們不能去嗎?”
“都說了是老年代了,是我這種老年對(duì)象去的地方,你們新來的還要在Survivor To區(qū)和Survivor From區(qū)兜兜轉(zhuǎn)轉(zhuǎn)好些回合呢,等你們到我這把年紀(jì)就能過去了”
“啊,為什么這么麻煩,設(shè)置這么多區(qū)都是干嘛的啊?”小A急著問。
小B把手搭在小A的肩說到:“這里的管理員用的是標(biāo)記-復(fù)制算法來清理空間,所以需要在Eden區(qū)之外再設(shè)一個(gè)地方接收復(fù)制活下來的對(duì)象。”
“那加一個(gè)Survivor區(qū)就夠了啊,干嘛弄兩個(gè)Survivor區(qū)?”我也拋了一個(gè)問題。
小B把另一只手搭在了我的肩上,“這是為了讓存活的對(duì)象能夠在這邊反復(fù)流轉(zhuǎn),不要著急去老年代區(qū)域”
“那為什么Survivor比Eden小那么多?”,我繼續(xù)問到
“根據(jù)他們統(tǒng)計(jì)發(fā)現(xiàn),98%的對(duì)象都活不過一輪GC,留下來的都是少數(shù)。而且兩個(gè)Survivor區(qū)有一個(gè)要空著,如果太大就太浪費(fèi)了。”
聽著小B的話我們倆都陷入了沉思。
沒過一會(huì)兒,廣播又響了起來:“各線程注意,請(qǐng)進(jìn)入安全點(diǎn)等待,各分區(qū)注意,啟動(dòng)一次Minor GC”,剛剛平靜的心又一次懸了起來。
管理員又開始點(diǎn)名,這一次,我和小B都被點(diǎn)到了,而沒有聽到小A的名字。
我們跟小A告別了,離開了Survivor To區(qū),走到分叉路口,小B也跟我道別:“再見了朋友,如果有機(jī)會(huì),老年代等你來再聚”
接下來就只剩我一個(gè)對(duì)象了,跟隨陌生的對(duì)象隊(duì)伍來到了Survivor From區(qū),這里跟剛才的To區(qū)規(guī)模相當(dāng),只是隊(duì)伍比起之前那次又小了很多。
來到自己的位置坐好,看了看頭上的GC年齡位,我2歲了。
Finalizer對(duì)象
沒有了熟悉的朋友,獨(dú)自發(fā)著呆,等待著線程們來訪問我。
突然,有人拍了拍我的肩膀,我回頭看去,居然是小A,他跑的氣喘吁吁的。
“你不是沒有被念到名字,沒有對(duì)象再引用你了嗎,居然沒有被清理?”,再次看見小A,我有點(diǎn)難以置信。
“剛才真的好險(xiǎn),我都嚇?biāo)懒?,沒想到事情出現(xiàn)了轉(zhuǎn)機(jī)!”
“發(fā)生了什么,快告訴我!”,我迫不及待的想知道這一切究竟是怎么回事。
小A喘了幾口氣繼續(xù)說到:“就在你們走后,管理員又拿出了另外一份名單,我的名字居然在上面,我一打聽才知道原來檢查到有一個(gè)Finalizer對(duì)象還在引用我~”
“奇怪了,不是說沒有對(duì)象嗎,怎么又冒出了一個(gè)Finalizer對(duì)象?這是什么?”
“后來我見到了那個(gè)Finalizer對(duì)象,就在開始我們沒多遠(yuǎn)的位置,聽他說是因?yàn)槲宜鶎俚念愑懈采wfinalize方法,所以在我出生的時(shí)候,他也一同誕生,并且一直持有我的引用”
“那后來呢?”,我繼續(xù)追問。
“后來啊,他被管理員放進(jìn)了一個(gè)ReferenceQueue的隊(duì)列去了,他們把那地方叫F-Queue監(jiān)獄。等待一個(gè)名字也叫Finalizer的線程大叔去處理,通過Finalizer對(duì)象來調(diào)用我的finalize方法,之后就把我們之間的聯(lián)系切斷了”
“他要倒霉了!不過好在還是救了你一命”
“躲得了初一,躲不過十五,現(xiàn)在連Finalizer對(duì)象也沒引用我了,下一次GC我鐵定要完蛋的”,小A說完又低下了頭。
“別想那么多,做對(duì)象最重要的就是開心了,說不定下一次我陪你一起完蛋呢”
我倆剛剛說完,熟悉的廣播又想起了:“各線程注意,請(qǐng)進(jìn)入安全點(diǎn)等待,各分區(qū)注意,啟動(dòng)一次Minor GC”
很快,管理員就念到了我的名字,看來我還能撐下去??斓浇Y(jié)束的時(shí)候,管理員居然神奇般的念到了小A的名字。
“小A,你聽到了嗎,居然還有對(duì)象在引用你!”我高興的對(duì)小A說到,小A也使勁點(diǎn)點(diǎn)頭。
“我知道了,一定是Finalizer線程大哥在執(zhí)行我的finalize方法的時(shí)候,又把我和誰建立了聯(lián)系,對(duì),一定是這樣!”
我們?cè)僖淮螐腡o區(qū)來到了From區(qū),這一次又少了很多舊面孔,不過從Eden區(qū)來了不少新面孔。
往后的一段時(shí)間里,我們?cè)谶@兜兜轉(zhuǎn)轉(zhuǎn)了好多輪,終于看到頭上的年齡標(biāo)記慢慢變成了15歲。
Full GC
沒過多久,廣播再次響起,我和小A幸運(yùn)的再次被點(diǎn)到名字,隨后,管理員檢查了我和小A,發(fā)現(xiàn)我倆超齡了,直接給我們趕到了一條新的路上,我知道前面就是傳說中的老年代了。
來到這個(gè)陌生的地方,放眼望去,這里可比我待過的Eden區(qū)、From區(qū)、To區(qū)加起來還要大,里面有好多的對(duì)象,密密麻麻的,不過看上去一個(gè)個(gè)都不是省油的燈,畢竟能來到這里的對(duì)象,比起Eden區(qū)的那些萌新都是些老油條了。
我倆找到自己的位置坐下開始閑聊,這時(shí),從不遠(yuǎn)處走過來一個(gè)身影,走近一看正是之前的小B。
“唉,這不是小A嗎,記得你不是被清理了嗎,怎么來這兒了?”,對(duì)于小A的出現(xiàn),小B哥有些驚訝。
隨后小A也向小B聊起了之前的那段驚險(xiǎn)經(jīng)歷~
正在閑聊的時(shí)候,管理員突然進(jìn)來圈了一大片空閑的位置,創(chuàng)建了一個(gè)巨大的對(duì)象!眾對(duì)象都驚呆了!
“小B哥,這哥們什么來路,空降啊,直接到老年代!”我好奇的問到。
“沒辦法,誰叫人家體格大,Eden區(qū)要么裝不下,要么嫌給他復(fù)制過去復(fù)制過來太費(fèi)勁,所以直接給安排到這里了,不像我們要一點(diǎn)點(diǎn)熬過來。”
“各線程注意,請(qǐng)進(jìn)入安全點(diǎn)等待,各分區(qū)注意,啟動(dòng)一次Full GC“,熟悉的廣播又一次響起,只不過這一次聽到的是Full GC。
“看來內(nèi)存吃緊了啊!”小B嘆了口氣。
管理員又開始點(diǎn)名了,這一次,幸運(yùn)不再眷顧小A。
未完待續(xù)~~
彩蛋
一個(gè)線程小姐姐迎面向我走了過來。
“Hi,小朋友你好,我是3002號(hào)線程,現(xiàn)在我要來鎖定你,別動(dòng)哦,讓我檢查下你的MarkWord”
“lock位是01,Good!讓我再看看偏向鎖標(biāo)記位,呀!是個(gè)1,糟糕”,小姐姐皺起了眉頭。
欲知后事如何,請(qǐng)關(guān)注后續(xù)精彩......