JVM之G1收集器
Garbage-First,面向服务端的垃圾收集器。
- 并行与并发:充分利用多核环境减少停顿时间,
- 分代收集:不需要配合其它收集器
- 空间整合:整体上看属于标记整理算法,局部(region之间)数据复制算法,运作期间不会产生空间碎片
- 停顿可预测,建立可以预测的停顿时间模型。
内存管理:
- 将整个java堆划分为多个大小形同的区域region,新生代和老年代都是region的集合。可以有计划的避免在全区域内进行垃圾收集。
- 回收方式:跟踪每一个region里面的垃圾堆积的价值大小(回收所得的空间大小以及所需耗费时间的经验值),维护一个优先列表,每次根据允许的回收时间,优先回收价值最大的region(GI名字由来),
- region之间的引用,新生代和老年带之间的引用根据remebered set来避免全盘扫描,每一个region都维护一个remebered set,
- 初始标记-》并发标记-》最终标记-》筛选回收,类CMS
Gabage First: G1
allocation failture,当收集垃圾,从一个区域复制数据到另一个区域时,找不到可用区域时,会引发allocation failture,进而引起full gc (stop the world)
float garbage:snapshot-at-the-begining(SATB) 标记存活对象(并发标记开始之前处于存活状态的对象)
G1: gc暂停时间及吞吐量的
CMS替代者,
压缩(高效)整理收集器,
使用等值大小的region作为基本管理单元,极大减少浮动垃圾
垃圾回收时间的可预测性更高。允许自定义
传统:
G1:
等大小的region被赋予不同的角色功能。增加了灵活性。
==》全局并发标记
==》首先收集垃圾比较少的region,释放大量空间
==》在垃圾比较多的的region,执行垃圾收集,压缩。
G1使用可预测暂停模型,来满足用户设置的目标。
G1一边压缩收集垃圾,一边释放空间,多线程并行执行(stop the world),减少暂停时间。
区别于CMS的不压缩,ParallelOld的全局压缩,
G1不是实时垃圾回收器,尽可能的实现定义的目标。G1根据以往的收集经验,对在用户设定的暂停时间内能够收集多少region做出估计。模型相对准确,据此判断哪些,多少region需要被收集。
并发标记 + 并行收集
Full GC是单线程的,会stop the world
Remember Set(RSet):每一个region一个RSet,标记region中的对象引用,空间占用不超过5%.
Collection Set(CSet):需要被收集的region集合,CSet中的活跃数据将会被evalucated(copied/moved),可能包含eden,surrior,old,占用空间不超过1%
应用:
大堆(6左右,>=)运行,低GC延迟(<=0.5s)要求,
GC频繁;收集或者压缩时间长;收集对象年龄差异大。
区别:
CMS:老年代收集;通过并发收集减少暂停时间,通常来说,并发低延迟的收集器都不移动和压缩活跃数据;通过扩大堆大小来处理碎片化问题。
初始标记:对于青年代可达的老年代对象标记;暂停
并发标记:贯穿整个老年代,标记活跃对象。基于GC Roots
重新标记:检查并发标记阶段漏掉的对象。暂停
并发清理:清理收集非活跃对象(合并)
重置:清理数据结构,以备下次收集。
1:CMS管理下的堆结构
2:年轻代 eden survivor1 survivor2,老年代的对象分配位置后,不再移动。
3:对象从eden,一个survivor复制到另一个survivor,达到收集年龄阈值的,晋升到老年代。
4:yong gc
5:老年代CMS收集:初始标记,重新标记 stop the world
6:CMS并发清理
G1: XX:G1HeapRegionSize
年轻代G1收集:
1: G1结构:G1将heap划分为多个(2000左右)大小相等的region进行管理。region大小(1~32M)由jvm启动时决定
2:不同region被映射为逻辑上的不同功能区域,不同区域region不需要连续。活跃数据在不同region复制和移动,region并行收集
3:年轻代收集, STW,eden survivor大小根据存储的统计信息进行计算设置(为下一次收集使用),
heap划分为多个region管理;yong区域,不连续,易于改变大小;引发暂停;多线程并行收集;复制或升级。
老年代G1收集:
Phase
|
Description
|
(1) Initial Mark (Stop the World Event)
|
This is a stop the world event. With G1, it is piggybacked on a normal young GC. Mark survivor regions (root regions) which may have references to objects in old generation.
|
(2) Root Region Scanning
|
Scan survivor regions for references into the old generation. This happens while the application continues to run. The phase must be completed before a young GC can occur.
|
(3) Concurrent Marking
|
Find live objects over the entire heap. This happens while the application is running. This phase can be interrupted by young generation garbage collections.
|
(4) Remark (Stop the World Event)
|
Completes the marking of live object in the heap. Uses an algorithm called snapshot-at-the-beginning (SATB) which is much faster than what was used in the CMS collector.
|
(5) Cleanup (Stop the World Event and Concurrent)
|
|
(*) Copying (Stop the World Event)
|
These are the stop the world pauses to evacuate or copy live objects to new unused regions. This can be done with young generation regions which are logged as [GC pause (young)]. Or both young and old generation regions which are logged as [GC Pause (mixed)].
|
1:初始标记,STW。基于yong GC,标记survivor中可能引用老年代对象的对象,作为Root Region,并扫描
2:并发标记:贯穿整个堆内存,标记活跃对象,并立即清除,同时收集活跃对象统计信息。
3:重新标记:使用snapshot-at-the-beginning(SATB),移除,回收标记的空region。STW
4:清理/复制,G1选择最不活跃的region,以便最快收集。这些区域可以和yong GC同时收集,STW
清理:统计活跃对象,活跃区域(STW)=》清理RSet(STW)=》重置空的region=》归还到free list(并发)。
复制:移动活跃对象到未应用的区域(STW)
yong gc和old gc同时发生。
-XX:+UseG1GC
java -Xmx50m -Xms50m -XX:+UseG1GC -XX:MaxGCPauseMillis=200
-XX:MaxGCPauseMillis=200:
-XX:InitiatingHeapOccupancyPercent=45:触发GC heap使用百分比。
最佳实践:
不要设置年轻代大小 --Xmn;G1自动调整
XX:MaxGCPauseMillis:设置为能够满足90%请求的时间值。
Evacuation Failure:没有足够的空间。
解决:
增大-XX:G1ReservePercent; 预留座位假的堆上限百分比,默认10
增大-XX:ConcGCThreads 并发收集线程数,不同jvm,默认值不同
提前mark
Option and Default Value
|
Description
|
-XX:+UseG1GC
|
Use the Garbage First (G1) Collector:启用G1收集器
|
-XX:MaxGCPauseMillis=n
|
Sets a target for the maximum GC pause time. This is a soft goal, and the JVM will make its best effort to achieve it.:目标GC暂停时间,尽可能目标
|
-XX:InitiatingHeapOccupancyPercent=n
|
Percentage of the (entire) heap occupancy to start a concurrent GC cycle. It is used by GCs that trigger a concurrent GC cycle based on the occupancy of the entire heap, not just one of the generations (e.g., G1). A value of 0 denotes 'do constant GC cycles'. The default value is 45.:触发GC 堆使用比例,整个堆的占用比例,而不是某个分代区域,0意味着频繁收集,默认为45
|
-XX:NewRatio=n
|
Ratio of new/old generation sizes. The default value is 2.:年轻代/老年代比例 默认为2
|
-XX:SurvivorRatio=n
|
Ratio of eden/survivor space size. The default value is 8.:eden/survivor比例,默认为8,即 8 1 1
|
-XX:MaxTenuringThreshold=n
|
Maximum value for tenuring threshold. The default value is 15.:对象晋升老年代年龄阈值,默认15
|
-XX:ParallelGCThreads=n
|
Sets the number of threads used during parallel phases of the garbage collectors. The default value varies with the platform on which the JVM is running.:并行收集线程数
|
-XX:ConcGCThreads=n
|
Number of threads concurrent garbage collectors will use. The default value varies with the platform on which the JVM is running.:并发收集线程数
|
-XX:G1ReservePercent=n
|
Sets the amount of heap that is reserved as a false ceiling to reduce the possibility of promotion failure. The default value is 10.:预留预防提升失败的堆大小上限百分比,默认10
|
-XX:G1HeapRegionSize=n
|
With G1 the Java heap is subdivided into uniformly sized regions. This sets the size of the individual sub-divisions. The default value of this parameter is determined ergonomically based upon heap size. The minimum value is 1Mb and the maximum value is 32Mb.:G1分割堆为等大小的region,region大小默认由jvm根据效能设置,1~32M
|