【Java】垃圾回收原來是這麼回事


最近想複習一下JVM的知識。然後發現網上不少文章在寫JVM的垃圾回收算法時,都比較偏向於具體實現,而少有站在更高角度來看垃圾回收算法的文章。而我本人想對垃圾回收算法有個全景的認識,所以,就找到了這本《垃圾回收的算法與實現》(以下簡稱《垃圾回收》)。本篇博客就是嘗試對“全景”的總結。

  以下爲方便討論,垃圾回收縮寫成GC。

  爲什麼要有GC

  我時而聽到C++程序員說我們是被GC慣壞了的一代。的確是這樣的,我本人在學習GC算法時,大腦裏第一問題就是爲什麼需要GC這樣的東西。說明我已經認爲GC是理所當然了。

  總的一句話:沒有GC的世界,我們需要手動進行內存管理,而手動內存管理是純技術活,又容易出錯。

  既然我們寫的大多程序都是爲了解決現實業務問題,那麼,我們爲什麼不把這種純技術活自動化呢?但是自動化,也是有代價的。這是我的個人理解,不代表John McCarthy本人的理解

  “垃圾”的定義

  首先,我們要給個“垃圾”的定義,才能進行回收吧。書中給出的定義:把分配到堆中那些不能通過程序引用的對象稱爲非活動對象,也就是死掉的對象,我們稱爲“垃圾”。

  GC的定義

  因爲我們期望讓內存管理變得自動(只管用內存,不管內存的回收),我們就必須做兩件事情: 1. 找到內存空間裏的垃圾;2. 回收垃圾,讓程序員能再次利用這部分空間 。(《垃圾回收》 P2)只要滿足這兩項功能的程序,就是GC,不論它是在JVM中,還是在Ruby的VM中。

  但這只是兩個需求,並沒有說明GC應該何時找垃圾,何時回收垃圾等等更具體的問題,各類GC算法就是在這些更具體問題的處理方式上施展手腳。

  GC的歷史

  John McCarthy身爲Lisp之父和人工智能之父,同時,他也是GC之父。1960年,他在其論文中首次發佈了GC算法(其實是委婉的提出)。

  《垃圾回收》的作者認爲:

從50年前GC算法首次發佈以來,衆多研究者對其進行了各種各樣的研究,因此許多GC算法也得以發佈。但事實上,這些算法只不過是把前文中提到的三種算法進行組合或應用。也可以這麼說,1963年GC複製算法誕生時,GC的根本性內容就已經完成了。(《垃圾回收》 P4)

  那我們常常聽說的分代垃圾回收又是怎麼回事?作者是這樣說的:人們從衆多程序案例中總結出了一個經驗:“大部分的對象在生成後馬上就變成了垃圾,很少有對象能活得很久”。分代垃圾回收利用該經驗,在對象中導入了“年齡”的概念,經歷過一次GC後活下來的對象年齡爲1歲。(垃圾回收》 P141)

分代垃圾回收中把對象分類成幾代,針對不同的代使用不同的GC算法,我們把剛生成的對象稱爲新生代對象,到達一定年齡的對象則稱爲老年代對象。(《垃圾回收》 P142)

  好了,這下我總算知道爲什麼要分代了,我的總結是: 將對象根據存活概率進行分類,對存活時間長一些的對象,可以減少掃描“垃圾”的時間,以減少GC頻率和時長。根本思路就是對對象進行分類,才能針對各個分類採用不同的垃圾回收算法,以對各算法進行揚長避短。

  留一個問題給讀者:我們知道分代垃圾回收所採用的堆結構是:

  爲什麼新生代空間要分成“生成空間”和“倖存空間”,而倖存空間又分成兩塊大小相等的倖存空間1,倖存空間2?

  這些GC算法共同解決的問題

  上面我們說了,GC的定義只給出了需求,三種算法都爲實現這個需求,那麼它們總會遇到共同要解決的問題吧? 我嘗試總結出:

  • 如何分辨出什麼是垃圾?
  • 如何、何時搜索垃圾?
  • 如何、何時清除垃圾?

  這樣,只要涉及到垃圾回收,我就可以從這2點需求,3個共同問題(兩點三共)出發來討論、學習。

  如何評價GC算法?

  如果沒有評價標準,我們當然無法評估這些GC算法的性能。作者給出了4個標準:

  • 吞吐量: 單位時間內的處理能力
  • 最大暫停時間:GC執行過程中,應用暫停的時長。較大的吞吐量和較短的最大暫停時間不可兼得
  • 堆的使用效率:就是堆空間的利用率。可用的堆越大,GC運行越快;相反,越想有效地利用有限的堆,GC花費的時間就越長。
  • 訪問的局部性:把具有引用關係的對象安排在堆中較近的位置,就能提高在緩存中讀取到想利用的數據的概率。

  好吧。兩點三共,四標~

  小結

  搞清楚爲什麼要GC,要實現GC都要解決什麼問題,而各類算法又是怎麼解決的,最後怎麼評價這些算法。GC原來是這麼回事。

  但是這不是GC的全部。但是提供我一個思考GC的思考框架。

  以上就是《垃圾回收的算法與實現》的讀書筆記。如果想更深入,可以閱讀《垃圾回收算法手冊:自動內存管理的藝術》。


作者:翟志軍

原文鏈接:點擊打開鏈接


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章