JVM 從入門到實戰 | 03 簡述垃圾回收演算法

程式猿雜貨鋪發表於2019-03-19

引言

之前我們學習了 JVM 基本介紹 以及 什麼樣的物件需要被 GC ,今天就來學習一下 JVM 在判斷出一個物件需要被 GC 會採用何種方式進行 GC。在學習 JVM 如何進行垃圾回收方法時,發現所謂的 JVM 垃圾回收思想和現實生活的場景有很多相似的地方。所以本文用餐廳回收餐桌的方式類比 JVM 垃圾回收演算法,應該能幫助 JVM 學習的理解和記憶。

經典垃圾回收算

標記-清除(Mark-Sweep)

研發園開了家新餐廳,餐廳老闆在考慮如何回收餐盤時首先使用了最簡單的方式,那就是服務員在顧客用餐的過程中,不定時的觀察餐廳,針對用完餐的顧客記錄他們的位置(當然一般的服務員的腦海中自行處理),統一回收他們的餐具和餐盤。但是這種回收方式會有一個明顯的問題,那就是回收後的餐廳座位,很有可能是不連續的。如果後續有同行的顧客(比如小情侶... ...)想坐在一起,那很可能找不到連續的座位。

JVM 從入門到實戰 | 03 簡述垃圾回收演算法

複製演算法(Copying)

為了解決餐廳座位碎片化的問題,餐廳的老闆提出了一個大膽的想法,這是一個很會思考的老闆。把餐廳的用餐區域分成兩部分 A 廳和 B 廳,當對 A 廳中的餐桌做回收時,將 A 廳中還未用完餐的顧客,"請"到 B 廳去用餐,並且讓這些顧客在 B 廳中拼桌用餐(為了餐位連續)。這樣所有 A 廳中的位置都空餘出來了,並且 B 廳中的用餐區域和未用餐區域都是連續的!簡直是強迫症晚期。看似完美的解決了回收後餐位碎片化的問題。但是依然帶來了其他的一些問題。

缺點:

  • 餐廳的運營區域是一個整體,現在只能同時對外開放 A 廳,運營空間變小了;

  • 當有很多顧客需要從 A 廳轉移到 B 廳時,效率太低;

  • 用餐體驗很差,不被罵娘才怪。

優點:

  • 不容易產生碎片

JVM 從入門到實戰 | 03 簡述垃圾回收演算法

標記-整理演算法(Mark-Compact)

當實行複製演算法解決餐位回收後不連續的問題,餐廳的老闆針對新問題又有了新想法,只要移動顧客就可以解決碎片化問題,為啥我要將餐廳分成兩個的部分呢?畢竟那樣不能最大效率的利用餐廳的用餐區域。創造性的提出了標記-整理演算法,結合前面兩中方法的優缺點,當餐廳準備回收餐位時,移動所有未用晚餐的顧客,並且讓從餐廳的第一桌開始拼桌。這樣保證後面的餐桌都是已經回收了餐盤的並且回收後的座位都是連續的。這樣既提高了餐廳餐桌的利用率又保證了當有大量組團顧客進店用餐時,餐廳能夠提供大量的連續餐桌(這個例子不恰當,如果真的碰到一個要讓人不斷移動形成空位的餐廳,你怕是要開噴了)。

JVM 從入門到實戰 | 03 簡述垃圾回收演算法

分代收集(Generational Collection)

如果還是用開餐廳的方式來思考 JVM 的話,可以把分代回收看做餐廳針對不同顧客的等級推出的個性化服務。分代收集演算法並沒有新的思想,只是根據物件存活週期的不同將記憶體劃分為幾塊,一般把 Java 堆分為新生代和老年代,這樣就可以根據各個年代的特點採用最適當的收集演算法。在新生代中,大量的物件都是“朝生夕死”,每次垃圾回收時,都可以發現大量物件死去,所以針對新生代的垃圾回收一般選擇複製演算法。只需要複製少量存活物件就可以完成收集。針對老年代的垃圾回收,物件的存活時間較長,就必須使用標記-清除或者標記-整理演算法來進行回收。

在新生代中,絕大多數的物件都是“朝生夕死”的,新生代並不需要按照 1:1 的比例劃分記憶體空間,而是將記憶體分為一個較大的 Eden 空間和一個較小的 Survivor 空間,並將 Survivor 空間分成兩個較小空間,分別是 From Space 和 ToSpace。每次使用 Eden 空間和其中的一塊 Survivor 空間,當進行回收時,將該兩塊空間中還存活的物件複製到另一塊 Survivor 空間中。Hotspot 虛擬機器預設 Eden 和 Survivor 的大小比例是 8:1,也就是每次新生代可用記憶體空間為整個新生代容量的 90%。

JVM 從入門到實戰 | 03 簡述垃圾回收演算法

這裡很顯然會有一個問題,理論上每次新生代 GC 都會回收絕大多數的物件,但是無法保證 GC 存活後的物件大學都不超過整個新生代的 10%。當 Survivor 空間的記憶體不夠用是,就需要老年代做記憶體擔保(分配擔保策略,前邊兩篇文章有提過,讀者可自行查閱)。同樣用餐廳的理論來理解,你希望把 A 廳的顧客轉移到 B 廳,但是 B 廳已經沒有足夠空間容納所有顧客了,這時候可以選擇將顧客安置在 VIP 包廂【老年代】。並且每次在新生代 GC 中存活的物件,其年齡就會 +1,預設情況下年齡達到 15 的物件會被轉移到老年代。

這裡也可以簡單理解為我們給餐廳的忠實吃貨辦了張 VIP 卡... ...

所以,同學,辦卡嗎?辦卡享五折優惠哈!

... ...

參考文件

《深入理解Java虛擬機器》周志明 著


相關文章