上篇我們知道垃圾回收機制,接下來,我們具體到垃圾回收器,看看JVM到底有哪些垃圾回收器。
一.GC效能指標
不可能三角
- 吞吐量:執行使用者程式碼的時間佔總執行時間的比例
- 暫停時間:進行GC時,使用者執行緒被暫停的時間(STW)
- 記憶體佔用:JAVA堆所佔記憶體的大小,這一點隨著硬體的發展,越來越容易實現
主要矛盾:你要暫停時間短,你就需要頻繁GC。但是多次GC,會導致吞吐量低。現在標準:在保證最大吞吐量的前提下,降低暫停的時間
二.七款垃圾回收器
- 序列回收器:Serial,Serial Old
- 並行回收器:ParNew,Parallel Scavenge,Parallel Old
- 併發回收器:CMS,G1
接下來看它們幾個的關係圖:
說明:
- 紅色虛線:jdk8廢棄它們2組的組合
- 綠色虛線:jdk14棄用Parallel Scavenge和Serial Old組合
- 青色虛線:jdk14刪除CMS回收器
接下來我們分別進行討論
Serial/Serial Old
- 最基本,最歷史悠久的回收器
- 序列回收器,Serial使用在新生代,Serial Old使用在老年代。 新生代採用複製演算法,老年代使用標記壓縮演算法。
- 這種回收器只有在限定單核cpu才使用,現在已經很少使用了
ParNew
- 並行回收器,多核情況下比Serial的要高,單核下沒有Serial高。
- 用在新生代,採用複製演算法。老年代使用Serial Old
Parallel/Parallel Old
- 吞吐量優先,java8預設的垃圾收集器
- Parallel採用複製演算法,Parallel Old採用標記壓縮演算法
- Parallel與ParNew不同的是,Parallel目的為了達到一個可控的吞吐量,具有自適應調解策略
- -XX:+UseAdaptiveSizePolicy: 開啟自適應調節策略,年輕代的大小,eden,s的比例,,晉升老年代等引數會自動調節。在手動調優比較困難的情況下,可以開啟這種模式
- -XX:+UseAdaptiveSizePolicy: 開啟自適應調節策略,年輕代的大小,eden,s的比例,,晉升老年代等引數會自動調節。在手動調優比較困難的情況下,可以開啟這種模式
- 適用於後臺運算而不需要太多互動的任務。比如批量處理,訂單處理,工資支付,科學計算等
三.CMS回收器
- CMS (Concurrent-Mark-Sweep)
- 低延遲(低暫停時間),第一款併發回收器,但不代表沒有STW
CMS的回收過程:CMS回收器的過程要比其他的都複雜,主要分為四個階段:
- 初始標記:只標記GC Roots直接關聯的物件。產生STW
- 併發標記:從GC Roots直接關聯的物件開始,向下遍歷物件圖。不產生STW
- 重新標記:為了修正在併發標記期間,使用者執行緒產生的新的物件。產生STW
- 併發清除:標記-清除。不產生STW
總結:在初始標記和重新標記階段都會暫停使用者執行緒,產生STW,但是STW的時間很短。 其他階段都是併發進行,不產生STW。所以CMS雖然是併發垃圾回收器,但是整體上還是會產生 STW,只是說STW的時間較短。因為最費時的併發標記與清除標記都不需要暫停工作,所以整體 上的低暫停時間的
CMS的缺點:
- 採用標記-清除演算法會產生記憶體碎片
- 對CPU資源敏感,CPU數量少會導致使用者程式執行速度降低較多。
- 產生浮動垃圾,浮動垃圾就是在併發標記階段產生的新垃圾。雖然重新標記可以標記一些新產生的垃圾,但是對於GC Roots直接引用的物件(比如new),沒有辦法進行標記。
那為什麼不適應標記-壓縮演算法?
- 因為在併發清除的時候,使用者執行緒沒有暫停。如果使用標記整理演算法,就需要移動使用者執行緒在記憶體中的位置。要保證使用者執行緒正常使用,前提是它執行的資源不受影響, 所以必須在STW情況下,才可以進行整理。
總結:關於記憶體碎片雖然也可以設定整理演算法解決,但是效果不好。垃圾回收過程中,必須暫停使用者執行緒的時間。 而現在CMS要進行併發,那麼就導致垃圾回收過程中,使用者執行緒還在製造新的垃圾的現象。 所以CMS後來被移除掉了,就是因為它為了達到低延遲,犧牲了太多東西,也造成了太多的問題。 jdk9.0被移除,但是還可以用。會報錯 。jdk14.0就徹底的被清除了。
四.G1垃圾回收器
- 分割槽回收器,並行與併發,同時還是分代收集(兼顧老年代和年輕代)。
- 將記憶體分為不同的區域(Region),在可控制的延遲時間下(讓垃圾回收控制在一個時間段內),優先回收垃圾量最大的區域。 在延遲可控的情況下,儘可能獲得高吞吐量。(想著把吞吐量和暫停時間都儘可能的兼顧)
- 主要是依靠的特色為:分割槽的原因,回收的範圍小。 而且G1會把這些region放在一個優先列表中,每次垃圾回收,會在指定的時間內,收集最有價值的region區域。 達到高效的收集。
- Region之間是複製演算法,整體上可以看作是標記壓縮演算法。
寄語:堅持也是一種超能力