(點擊上方公眾號,可快速關注)
來源:翟志軍,
showme.codes/2017-02-04/what-is-gc/
如有好文章投稿,請點擊 → 這裡了解詳情
摘要:John McCarthy身為Lisp之父和人工智慧之父,同時,他也是GC之父。1960年,他在其論文中首次發布了GC算法(其實是委婉的提出)。而Java的前身Oak是在1990發布的,利用JVM實現了跨平臺。GC因此一舉成名。
最近想複習一下JVM的知識。然後發現網上不少文章在寫JVM的垃圾回收算法時,都比較偏向於具體實現,而少有站在更高角度來看垃圾回收算法的文章。而我本人想對垃圾回收算法有個全景的認識,所以,就找到了這本《垃圾回收的算法與實現》(以下簡稱《垃圾回收》)。本篇博客就是嘗試對「全景」的總結。
以下為方便討論,垃圾回收縮寫成GC。
為什麼要有GC
我時而聽到C++程式設計師說我們是被GC慣壞了的一代。的確是這樣的,我本人在學習GC算法時,大腦裡第一問題就是為什麼需要GC這樣的東西。說明我已經認為GC是理所當然了。
總的一句話:沒有GC的世界,我們需要手動進行內存管理,而手動內存管理是純技術活,又容易出錯。
既然我們寫的大多程序都是為了解決現實業務問題,那麼,我們為什麼不把這種純技術活自動化呢?但是自動化,也是有代價的。 這是我的個人理解,不代表John McCarthy本人的理解。
「垃圾」的定義
首先,我們要給個「垃圾」的定義,才能進行回收吧。書中給出的定義: > 把分配到堆中那些不能通過程序引用的對象稱為非活動對象,也就是死掉的對象,我們稱為「垃圾」。
GC的定義
因為我們期望讓內存管理變得自動(只管用內存,不管內存的回收),我們就必須做兩件事情: > 1. 找到內存空間裡的垃圾 > 2. 回收垃圾,讓程式設計師能再次利用這部分空間 [1] 只要滿足這兩項功能的程序,就是GC,不論它是在JVM中,還是在Ruby的VM中。
但這只是兩個需求,並沒有說明GC應該何時找垃圾,何時回收垃圾等等更具體的問題,各類GC算法就是在這些更具體問題的處理方式上施展手腳。
GC的歷史
John McCarthy身為Lisp之父和人工智慧之父,同時,他也是GC之父。1960年,他在其論文中首次發布了GC算法(其實是委婉的提出😂)。
標記-清除算法 由John McCarthy在1960年提出
引用計數法 由George E. Collins在1960年提出 此算法會有循環引用問題,Harold McBeth 1963年指出。
複製算法 由Marvin L. Minsky在1963年提出
《垃圾回收》的作者認為:
從50年前GC算法首次發布以來,眾多研究者對其進行了各種各樣的研究,因此許多GC算法也得以發布。[2] 但事實上,這些算法只不過是把前文中提到的三種算法進行組合或應用。也可以這麼說,1963年GC複製算法誕生時,GC的根本性內容就已經完成了。[3]
那我們常常聽說的分代垃圾回收又是怎麼回事?作者是這樣說的: > 人們從眾多程序案例中總結出了一個經驗:「大部分的對象在生成後馬上就變成了垃圾,很少有對象能活得很久」。分代垃圾回收利用該經驗,在對象中導入了「年齡」的概念,經歷過一次GC後活下來的對象年齡為1歲。[4]
分代垃圾回收中把對象分類成幾代,針對不同的代使用不同的GC算法,我們把剛生成的對象稱為新生代對象,到達一定年齡的對象則稱為老年代對象。[5]
好了,這下我總算知道為什麼要分代了,我的總結是: 將對象根據存活概率進行分類,對存活時間長一些的對象,可以減少掃描「垃圾」的時間,以減少GC頻率和時長。根本思路就是對對象進行分類,才能針對各個分類採用不同的垃圾回收算法,以對各算法進行揚長避短。
留一個問題給讀者:我們知道分代垃圾回收所採用的堆結構是:
為什麼新生代空間要分成「生成空間」和「倖存空間」,而倖存空間又分成兩塊大小相等的倖存空間1,倖存空間2?
這些GC算法共同解決的問題
上面我們說了,GC的定義只給出了需求,三種算法都為實現這個需求,那麼它們總會遇到共同要解決的問題吧? 我嘗試總結出:
如何分辨出什麼是垃圾?
如何、何時搜索垃圾?
如何、何時清除垃圾?
這樣,只要涉及到垃圾回收,我就可以從這2點需求,3個共同問題(兩點三共)出發來討論、學習。
如何評價GC算法?
如果沒有評價標準,我們當然無法評估這些GC算法的性能。作者給出了4個標準:
吞吐量: 單位時間內的處理能力
最大暫停時間:GC執行過程中,應用暫停的時長。 較大的吞吐量和較短的最大暫停時間不可兼得
堆的使用效率:就是堆空間的利用率。 可用的堆越大,GC運行越快;相反,越想有效地利用有限的堆,GC花費的時間就越長。
訪問的局部性:把具有引用關係的對象安排在堆中較近的位置,就能提高在緩存中讀取到想利用的數據的概率。
好吧。兩點三共,四標~
小結
搞清楚為什麼要GC,要實現GC都要解決什麼問題,而各類算法又是怎麼解決的,最後怎麼評價這些算法。GC原來是這麼回事。
但是這不是GC的全部。但是提供我一個思考GC的思考框架。
以上就是《垃圾回收的算法與實現》的讀書筆記。如果想更深入,可以閱讀《垃圾回收算法手冊:自動內存管理的藝術》。
[1] 《垃圾回收的算法與實現》 P2
[2][3] 《垃圾回收的算法與實現》 P4
[4] 《垃圾回收的算法與實現》 P141
[5] 《垃圾回收的算法與實現》 P142
覺得本文對你有幫助?請分享給更多人
關注「ImportNew」,提升Java技能