G1是一款面向服务端应用的垃圾收集器。初次发布是在JDK 7这一版本中。长久的目标是替代CMS收集器。
1.介绍
1.1 G1收集器通过下面一些方法实现了高性能和减少暂停时间的目的
首先将Java堆空间划分为一些大小相等的区域(region),每个区域都是虚拟机中的一段连续内存空间。G1通过执行并发的全局标记来确定整个Java堆空间中存活的对象。标记阶段完成后,G1就知道哪些区域基本上是空闲的。在回收内存时优先回收这些区域,这样通常都会回收相当数量的内存。这就是为什么它叫做Garbage-First的原因。顾名思义G1关注某些区域的回收和整理,这些区域中的对象很有可能被完全回收。而且G1使用了一个暂停时间预测模型使得暂停时间控制在用户指定的暂停时间内,并根据用户指定的暂停时间来选择合适的区域回收内存。
G1确定了可回收的区域后就是筛选回收(evacuation)阶段了。在此阶段将对象从一个或多个区域复制到单一区域,同时整理和释放内存。该阶段是在多个处理器上多个线程并行进行的,因此减少了暂停时间并提高了吞吐量。G1在每一次的垃圾收集过程中都不断地减少碎片,并能够将暂停时间控制在一定范围内。这些已经是以前的垃圾收集器无法完成的了。比如:CMS收集器并不做内存整理。ParallelOld收集器只是对整个Java堆空间做整理,这样导致相当长的暂停时间。
关于G1很重要的一点是它并不是一个实时收集器。尽管在绝大多数情况下都能够满足暂停时间的要求,但并非没有例外。因为G1是基于之前数次垃圾收集的经验值来估计在用户指定的暂停时间内有多少区域可以收集。因此它对于在区域上执行收集的成本有一个合理的较为精确的模型,并使用该模型来确定对哪些区域执行收集。
G1确定了可回收的区域后就是筛选回收(evacuation)阶段了。在此阶段将对象从一个或多个区域复制到单一区域,同时整理和释放内存。该阶段是在多个处理器上多个线程并行进行的,因此减少了暂停时间并提高了吞吐量。G1在每一次的垃圾收集过程中都不断地减少碎片,并能够将暂停时间控制在一定范围内。这些已经是以前的垃圾收集器无法完成的了。比如:CMS收集器并不做内存整理。ParallelOld收集器只是对整个Java堆空间做整理,这样导致相当长的暂停时间。
关于G1很重要的一点是它并不是一个实时收集器。尽管在绝大多数情况下都能够满足暂停时间的要求,但并非没有例外。因为G1是基于之前数次垃圾收集的经验值来估计在用户指定的暂停时间内有多少区域可以收集。因此它对于在区域上执行收集的成本有一个合理的较为精确的模型,并使用该模型来确定对哪些区域执行收集。
1.2 推荐使用的场景
G1的首要目的是为那些需要大容量内存和较小GC延迟的应用程序提供解决方案。这通常是指那些堆大小设置在6GB以上,确定的、可以预测的暂停时间在0.5秒以内的应用程序。如果应用程序符合以下一项或者多项特征,那么从CMS或者ParallelOld收集器切换到G1可能更合适。
活动对象占据了超过50%的Java堆空间。
对象分配率或者提升率波动明显。
不希望有长时间的垃圾收集暂停时间(超过0.5秒或1秒)。
1.3 G1的前景
G1的使命是替换掉CMS收集器。通过对比G1和CMS收集器,可以发现G1是更好的一种解决方案。首先G1是一个压缩收集器,G1通过充分的压缩完全避免了使用细粒度的空闲列表(free lists)来分配内存,而是使用相对粗粒度的区域(regions)来分配内存。这明显简化了收集器,也很大程度上减少了内存碎片化的问题。此外,相比较CMS,G1可以预测出垃圾收集的暂停时间,并允许用户指定期望的暂停时间。2.参数
它既能管理新生代,也能管理老年代,所以
不需要和其他收集器搭配。
-XX:+UseG1GC //指定使用G1收集器
-XX:MaxGCPauseMillis=300 //期望一次回收暂停时间不要超过300毫秒
3.日志格式
解读文章可参加Oracle blog:
https://blogs.oracle.com/g1gc/entry/g1gc_logs_how_to_print
OpenJDK 64-Bit Server VM (25.66-b60) for linux-amd64 JRE (1.8.0_66-b60), built on Dec 2 2015 09:54:46 by "admin" with gcc 4.4.7 Memory: 4k page, physical 8388608k(5097132k free), swap 1999864k(1999864k free) CommandLine flags: -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/logs/java.hprof -XX:InitialHeapSize=4294967296 -XX:MaxGCPauseMillis=300 -XX:MaxHeapSize=4294967296 -XX:MaxMetaspaceSize=402653184 -XX:MaxNewSize=2147483648 -XX:NewSize=2147483648 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC 2016-11-17T11:11:10.789+0800: 3.552: [GC pause (Metadata GC Threshold) (young) (initial-mark), 0.1077120 secs] [Parallel Time: 39.1 ms, GC Workers: 4] [GC Worker Start (ms): Min: 3552.8, Avg: 3552.8, Max: 3552.8, Diff: 0.0] [Ext Root Scanning (ms): Min: 1.4, Avg: 1.6, Max: 2.0, Diff: 0.5, Sum: 6.3] [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0] [Processed Buffers: Min: 0, Avg: 0.0, Max: 0, Diff: 0, Sum: 0] [Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1] [Code Root Scanning (ms): Min: 0.5, Avg: 0.8, Max: 1.2, Diff: 0.6, Sum: 3.1] [Object Copy (ms): Min: 36.3, Avg: 36.5, Max: 36.9, Diff: 0.6, Sum: 146.1] [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0] [Termination Attempts: Min: 1, Avg: 2.0, Max: 3, Diff: 2, Sum: 8] [GC Worker Other (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.0, Sum: 0.2] [GC Worker Total (ms): Min: 38.9, Avg: 39.0, Max: 39.0, Diff: 0.1, Sum: 155.8] [GC Worker End (ms): Min: 3591.7, Avg: 3591.7, Max: 3591.8, Diff: 0.0] [Code Root Fixup: 0.6 ms] [Code Root Purge: 0.1 ms] [Clear CT: 0.1 ms] [Other: 67.8 ms] [Choose CSet: 0.0 ms] [Ref Proc: 66.5 ms] [Ref Enq: 0.1 ms] [Redirty Cards: 0.1 ms] [Humongous Register: 0.0 ms] [Humongous Reclaim: 0.0 ms] [Free CSet: 0.4 ms] [Eden: 328.0M(2048.0M)->0.0B(1982.0M) Survivors: 0.0B->66.0M Heap: 328.0M(4096.0M)->64.6M(4096.0M)] [Times: user=0.18 sys=0.04, real=0.11 secs] 2016-11-17T11:11:10.898+0800: 3.661: [GC concurrent-root-region-scan-start] 2016-11-17T11:11:10.958+0800: 3.721: [GC concurrent-root-region-scan-end, 0.0602273 secs] 2016-11-17T11:11:10.958+0800: 3.721: [GC concurrent-mark-start] 2016-11-17T11:11:10.958+0800: 3.721: [GC concurrent-mark-end, 0.0006063 secs] 2016-11-17T11:11:10.959+0800: 3.722: [GC remark 2016-11-17T11:11:10.959+0800: 3.722: [Finalize Marking, 0.0003445 secs] 2016-11-17T11:11:10.959+0800: 3.722: [GC ref-proc, 0.0000522 secs] 2016-11-17T11:11:10.959+0800: 3.722: [Unloading, 0.0050686 secs], 0.0057804 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 2016-11-17T11:11:10.964+0800: 3.728: [GC cleanup 78M->78M(4096M), 0.0035612 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 2016-11-17T11:11:13.361+0800: 6.124: [GC pause (Metadata GC Threshold) (young) (initial-mark), 0.1394786 secs] [Parallel Time: 51.8 ms, GC Workers: 4] [GC Worker Start (ms): Min: 6124.5, Avg: 6124.6, Max: 6124.8, Diff: 0.3] [Ext Root Scanning (ms): Min: 2.4, Avg: 3.2, Max: 4.4, Diff: 1.9, Sum: 12.7] [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0] [Processed Buffers: Min: 0, Avg: 0.0, Max: 0, Diff: 0, Sum: 0] [Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.1] [Code Root Scanning (ms): Min: 0.0, Avg: 0.6, Max: 2.5, Diff: 2.5, Sum: 2.6] [Object Copy (ms): Min: 46.5, Avg: 47.6, Max: 48.7, Diff: 2.1, Sum: 190.6] [Termination (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 0.4] [Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 4] [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1] [GC Worker Total (ms): Min: 51.4, Avg: 51.6, Max: 51.7, Diff: 0.3, Sum: 206.6] [GC Worker End (ms): Min: 6176.2, Avg: 6176.2, Max: 6176.3, Diff: 0.0] [Code Root Fixup: 0.8 ms] [Code Root Purge: 0.0 ms] [Clear CT: 0.3 ms] [Other: 86.6 ms] [Choose CSet: 0.0 ms] [Ref Proc: 85.4 ms] [Ref Enq: 0.1 ms] [Redirty Cards: 0.1 ms] [Humongous Register: 0.0 ms] [Humongous Reclaim: 0.0 ms] [Free CSet: 0.5 ms] [Eden: 508.0M(1982.0M)->0.0B(1974.0M) Survivors: 66.0M->74.0M Heap: 571.6M(4096.0M)->73.0M(4096.0M)] [Times: user=0.29 sys=0.05, real=0.14 secs] 2016-11-17T11:11:13.501+0800: 6.264: [GC concurrent-root-region-scan-start] 2016-11-17T11:11:13.569+0800: 6.332: [GC concurrent-root-region-scan-end, 0.0679650 secs] 2016-11-17T11:11:13.569+0800: 6.332: [GC concurrent-mark-start] 2016-11-17T11:11:13.570+0800: 6.333: [GC concurrent-mark-end, 0.0006412 secs] 2016-11-17T11:11:13.570+0800: 6.333: [GC remark 2016-11-17T11:11:13.570+0800: 6.333: [Finalize Marking, 0.0003852 secs] 2016-11-17T11:11:13.570+0800: 6.334: [GC ref-proc, 0.0000721 secs] 2016-11-17T11:11:13.570+0800: 6.334: [Unloading, 0.0060320 secs], 0.0068158 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 2016-11-17T11:11:13.577+0800: 6.340: [GC cleanup 76M->76M(4096M), 0.0041485 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]