- JVM G1源碼分析和調優
- 彭成寒
- 1119字
- 2019-04-22 18:14:52
1.4.4 垃圾優先回收
垃圾優先回收器(Garbage-First,也稱為G1)從JDK7 Update 4開始正式提供。G1致力于在多CPU和大內存服務器上對垃圾回收提供軟實時目標和高吞吐量。G1垃圾回收器的設計和前面提到的3種回收器都不一樣,它在并行、串行以及CMS GC針對堆空間的管理方式上都是連續的,如圖1-7所示。

圖1-6 并發標記回收

圖1-7 連續空間管理
連續的內存將導致垃圾回收時收集時間過長,停頓時間不可控。因此G1將堆拆成一系列的分區(Heap Region),這樣在一個時間段內,大部分的垃圾收集操作只針對一部分分區,而不是整個堆或整個(老生)代,如圖1-8所示。

圖1-8 分區空間管理
在G1里,新生代就是一系列的內存分區,這意味著不用再要求新生代是一個連續的內存塊。類似地,老生代也是由一系列的分區組成。這樣也就不需要在JVM運行時考慮哪些分區是老生代,哪些是新生代。事實上,G1通常的運行狀態是:映射G1分區的虛擬內存隨著時間的推移在不同的代之間切換。例如一個G1分區最初被指定為新生代,經過一次新生代的回收之后,會將整個新生代分區都劃入未使用的分區中,那它可以作為新生代分區使用,也可以作為老生代分區使用。很可能在完成一個新生代收集之后,一個新生代的分區在未來的某個時刻可用于老生代分區。同樣,在一個老生代分區完成收集之后,它就成為了可用分區,在未來某個時候可作為一個新生代分區來使用。
G1新生代的收集方式是并行收集,采用復制算法。與其他JVM垃圾回收器一樣,一旦發生一次新生代回收,整個新生代都會被回收,這也就是我們常說的新生代回收(Young GC)。但是G1和其他垃圾回收器不同的地方在于:
·G1會根據預測時間動態改變新生代的大小。
其他垃圾回收新生代的大小也可以動態變化,但這個變化主要是根據內存的使用情況進行的。G1中則是以預測時間為導向,根據內存的使用情況調整新生代分區的數目。
·G1老生代的垃圾回收方式與其他JVM垃圾回收器對老生代處理有著極大的不同。G1老生代的收集不會為了釋放老生代的空間對整個老生代做回收。相反,在任意時刻只有一部分老生代分區會被回收,并且,這部分老生代分區將在下一次增量回收時與所有的新生代分區一起被收集。這就是我們所說的混合回收(Mixed GC)。在選擇老生代分區的時候,優先考慮垃圾多的分區,這也正是垃圾優先這個名字的由來。后續我們將逐一介紹這些內容。
在G1中還有一個概念就是大對象,指的是待分配的對象大小超過一定的閾值之后,為了減少這種對象在垃圾回收過程的復制時間,直接把對象分配到老生代分區中而不是新生代分區中。
從實現角度來看,G1算法是復合算法,吸收了以下算法的優勢:
·列車算法,對內存進行分區,參見圖1-8。
·CMS,對分區進行并發標記。
·最老優先,最老的數據(通常也是垃圾)優先收集。
關于列車算法、CMS和最老優先可以參考其他的書籍,這里不再贅述。
- Deploying Node.js
- C++面向對象程序設計(微課版)
- C# 從入門到項目實踐(超值版)
- PyTorch自然語言處理入門與實戰
- TypeScript實戰指南
- 零基礎輕松學SQL Server 2016
- Bootstrap 4 Cookbook
- Unity 2018 Shaders and Effects Cookbook
- Cocos2d-x Game Development Blueprints
- Raspberry Pi Robotic Blueprints
- 微前端設計與實現
- Learning C++ by Creating Games with UE4
- JavaScript前端開發基礎教程
- Java EE輕量級解決方案:S2SH
- 劍指大數據:企業級電商數據倉庫項目實戰(精華版)