摘要:John McCarthy身為Lisp之父和人工智能之父晰房,同時还绘,他也是GC之父。1960年如庭,他在其論文中首次發(fā)布了GC算法(其實是委婉的提出??)。而Java的前身Oak是在1990發(fā)布的撼港,利用JVM實現(xiàn)了跨平臺坪它。GC因此一舉成名。
最近想復(fù)習一下JVM的知識帝牡。然后發(fā)現(xiàn)網(wǎng)上不少文章在寫JVM的垃圾回收算法時往毡,都比較偏向于具體實現(xiàn),而少有站在更高角度來看垃圾回收算法的文章否灾。而我本人想對垃圾回收算法有個全景的認識,所以鸣奔,就找到了這本《垃圾回收的算法與實現(xiàn)》(以下簡稱《垃圾回收》)墨技。本篇博客就是嘗試對“全景”的總結(jié)。
以下為方便討論挎狸,垃圾回收縮寫成GC扣汪。
為什么要有GC
我時而聽到C++程序員說我們是被GC慣壞了的一代。的確是這樣的锨匆,我本人在學(xué)習GC算法時崭别,大腦里第一問題就是為什么需要GC這樣的東西。說明我已經(jīng)認為GC是理所當然了恐锣。??
總的一句話:沒有GC的世界茅主,我們需要手動進行內(nèi)存管理,而手動內(nèi)存管理是純技術(shù)活土榴,又容易出錯诀姚。
既然我們寫的大多程序都是為了解決現(xiàn)實業(yè)務(wù)問題,那么玷禽,我們?yōu)槭裁床话堰@種純技術(shù)活自動化呢赫段?但是自動化,也是有代價的矢赁。這是我的個人理解糯笙,不代表John McCarthy本人的理解。
“垃圾”的定義
首先撩银,我們要給個“垃圾”的定義给涕,才能進行回收吧。書中給出的定義: > 把分配到堆中那些不能通過程序引用的對象稱為非活動對象,也就是死掉的對象稠炬,我們稱為“垃圾”焕阿。
GC的定義
因為我們期望讓內(nèi)存管理變得自動(只管用內(nèi)存,不管內(nèi)存的回收)首启,我們就必須做兩件事情: > 1. 找到內(nèi)存空間里的垃圾 > 2.
回收垃圾暮屡,讓程序員能再次利用這部分空間 [1] 只要滿足這兩項功能的程序,就是GC毅桃,不論它是在JVM中褒纲,還是在Ruby的VM中。
但這只是兩個需求钥飞,并沒有說明GC應(yīng)該何時找垃圾莺掠,何時回收垃圾等等更具體的問題,各類GC算法就是在這些更具體問題的處理方式上施展手腳读宙。
GC的歷史
John McCarthy身為Lisp之父和人工智能之父彻秆,同時,他也是GC之父结闸。1960年唇兑,他在其論文中首次發(fā)布了GC算法(其實是委婉的提出??)。
標記-清除算法由John McCarthy在1960年提出
引用計數(shù)法由George E. Collins在1960年提出 此算法會有循環(huán)引用問題桦锄,Harold McBeth1963年指出扎附。
復(fù)制算法由Marvin L. Minsky在1963年提出
《垃圾回收》的作者認為:
從50年前GC算法首次發(fā)布以來,眾多研究者對其進行了各種各樣的研究结耀,因此許多GC算法也得以發(fā)布留夜。[2] 但事實上,這些算法只不過是把前文中提到的三種算法進行組合或應(yīng)用图甜。也可以這么說碍粥,1963年GC復(fù)制算法誕生時,GC的根本性內(nèi)容就已經(jīng)完成了黑毅。[3]
那我們常常聽說的分代垃圾回收又是怎么回事即纲?作者是這樣說的: >
人們從眾多程序案例中總結(jié)出了一個經(jīng)驗:“大部分的對象在生成后馬上就變成了垃圾,很少有對象能活得很久”博肋。分代垃圾回收利用該經(jīng)驗低斋,在對象中導(dǎo)入了“年齡”的概念,經(jīng)歷過一次GC后活下來的對象年齡為1歲匪凡。[4]
分代垃圾回收中把對象分類成幾代膊畴,針對不同的代使用不同的GC算法,我們把剛生成的對象稱為新生代對象病游,到達一定年齡的對象則稱為老年代對象唇跨。[5]
好了稠通,這下我總算知道為什么要分代了,我的總結(jié)是: 將對象根據(jù)存活概率進行分類买猖,對存活時間長一些的對象改橘,可以減少掃描“垃圾”的時間,以減少GC頻率和時長玉控。根本思路就是對對象進行分類飞主,才能針對各個分類采用不同的垃圾回收算法,以對各算法進行揚長避短高诺。
留一個問題給讀者:我們知道分代垃圾回收所采用的堆結(jié)構(gòu)是:
為什么新生代空間要分成“生成空間”和“幸存空間”碌识,而幸存空間又分成兩塊大小相等的幸存空間1,幸存空間2?
這些GC算法共同解決的問題
上面我們說了虱而,GC的定義只給出了需求筏餐,三種算法都為實現(xiàn)這個需求,那么它們總會遇到共同要解決的問題吧牡拇? 我嘗試總結(jié)出:
如何分辨出什么是垃圾魁瞪?
如何、何時搜索垃圾惠呼?
如何导俘、何時清除垃圾?
這樣罢杉,只要涉及到垃圾回收趟畏,我就可以從這2點需求贡歧,3個共同問題(兩點三共)出發(fā)來討論滩租、學(xué)習。
如何評價GC算法利朵?
如果沒有評價標準律想,我們當然無法評估這些GC算法的性能。作者給出了4個標準:
吞吐量: 單位時間內(nèi)的處理能力
最大暫停時間:GC執(zhí)行過程中绍弟,應(yīng)用暫停的時長技即。 較大的吞吐量和較短的最大暫停時間不可兼得
堆的使用效率:就是堆空間的利用率。 可用的堆越大樟遣,GC運行越快而叼;相反,越想有效地利用有限的堆豹悬,GC花費的時間就越長葵陵。
訪問的局部性:把具有引用關(guān)系的對象安排在堆中較近的位置,就能提高在緩存中讀取到想利用的數(shù)據(jù)的概率瞻佛。
好吧脱篙。兩點三共娇钱,四標~
小結(jié)
搞清楚為什么要GC,要實現(xiàn)GC都要解決什么問題绊困,而各類算法又是怎么解決的文搂,最后怎么評價這些算法。GC原來是這么回事秤朗。
但是這不是GC的全部煤蹭。但是提供我一個思考GC的思考框架。
以上就是《垃圾回收的算法與實現(xiàn)》的讀書筆記川梅。如果想更深入疯兼,可以閱讀《垃圾回收算法手冊:自動內(nèi)存管理的藝術(shù)》。