但是划分的区域之间有可能有相互引用。所以引出了Card Table和Rememberd Set的概念。Rememberd Set(RS)里存的是区域之间的引用。Card Table是把区域进一步细分。搜引用的时候只需要搜索很小的子区域。RS可以看成是一个哈希表,就是存引用关系的。是一种典型的空间换时间的做法。
对于每个区域使用的垃圾收集算法,实际上G1没有什么创新,年轻代还是并行拷贝,老年代主要采用并发标记配合增量压缩。算法方面也比较成熟了。
各种垃圾收集器的对比
怎样选择合适自己业务的垃圾收集器
从理论上,G1是为了替代CMS。我们这边的本质需求也是降低STW,也已经很成熟了。并发量大稳定性高的公司也在用。公司内部也有使用的经验。没有什么问题。
那就从实际上试验一把看看实际运行是否符合预期,并且要测试对G1专门的参数做微调。特别是MaxGCPauseMillis这个参数,因为这个参数设置的是预期每次GC的最大停顿时间。如果设置的不合理,比如太小就会造成GC频繁。如果太大,业务响应时间会很长。
实际上我有用实际代码模拟,但是为了信息安全这里自己用demo来说明。
JVM参数设置为:
-Xms4096m //最大堆设置
-Xmx4096m //最小堆设置
-XX:+UseG1GC //使用G1垃圾收集器
-XX:MaxGCPauseMillis=20 //最大GC停顿时间,默认是200ms,这里设置20ms
-XX:+PrintGCDetails //打印GC详情日志
-XX:+PrintStringTableStatistics //打印字符串常量、引用常量统计
-XX:+PrintSafepointStatistics //打印停顿原因
-XX:+PrintGCApplicationStoppedTime //停顿时间输出到GC日志中
上面参数中除了堆大小设置、使用G1和设置预期最大停顿时间外都是便于观察的统计信息。设置好之后可以根据自己的业务构造合适的案例。调整参数观察效果,同时也需要用cms的结果做对比。
[GC pause (G1 Humongous Allocation) (young), 0.0021237 secs] [Parallel Time: 1.4 ms, GC Workers: 8] [GC Worker Start (ms): Min: 3885.1, Avg: 3885.5, Max: 3886.4, Diff: 1.3] [Ext Root Scanning (ms): Min: 0.0, Avg: 0.2, Max: 0.5, Diff: 0.5, Sum: 1.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.0] [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.4, Diff: 0.4, Sum: 0.4] [Object Copy (ms): Min: 0.0, Avg: 0.7, Max: 1.0, Diff: 1.0, Sum: 5.3] [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.3] [Termination Attempts: Min: 1, Avg: 6.5, Max: 14, Diff: 13, Sum: 52] [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0] [GC Worker Total (ms): Min: 0.0, Avg: 0.9, Max: 1.3, Diff: 1.3, Sum: 7.4] [GC Worker End (ms): Min: 3886.4, Avg: 3886.4, Max: 3886.4, Diff: 0.0] [Code Root Fixup: 0.0 ms] [Code Root Purge: 0.0 ms] [Clear CT: 0.1 ms] [Other: 0.6 ms] [Choose CSet: 0.0 ms] [Ref Proc: 0.1 ms] [Ref Enq: 0.0 ms] [Redirty Cards: 0.1 ms] [Humongous Register: 0.2 ms] [Humongous Reclaim: 0.1 ms] [Free CSet: 0.0 ms] [Eden: 4096.0K(200.0M)->0.0B(202.0M) Survivors: 4096.0K->2048.0K Heap: 3405.5M(4096.0M)->3402.0M(4096.0M)] [Times: user=0.00 sys=0.00, real=0.00 secs] Total time for which application threads were stopped: 0.0027839 seconds, Stopping threads took: 0.0000253 seconds [Full GC (Allocation Failure) 3401M->3401M(4096M), 0.0487029 secs] [Eden: 0.0B(202.0M)->0.0B(204.0M) Survivors: 2048.0K->0.0B Heap: 3402.0M(4096.0M)->3401.4M(4096.0M)], [Metaspace: 5853K->5853K(1056768K)] [Times: user=0.06 sys=0.00, real=0.05 secs] [Full GC (Allocation Failure) 3401M->3401M(4096M), 0.0376090 secs] [Eden: 0.0B(204.0M)->0.0B(204.0M) Survivors: 0.0B->0.0B Heap: 3401.4M(4096.0M)->3401.4M(4096.0M)], [Metaspace: 5853K->5849K(1056768K)] [Times: user=0.03 sys=0.00, real=0.04 secs] Total time for which application threads were stopped: 0.0868891 seconds, Stopping threads took: 0.0000192 seconds Heap garbage-first heap total 4194304K, used 3483005K [0x00000006c0000000, 0x00000006c0204000, 0x00000007c0000000) region size 2048K, 1 young (2048K), 0 survivors (0K) Metaspace used 5924K, capacity 6074K, committed 6144K, reserved 1056768K class space used 687K, capacity 722K, committed 768K, reserved 1048576K vmop [threads: total initially_running wait_to_block] [time: spin block sync cleanup vmop] page_trap_count 1.121: no vm operation [ 12 0 1 ] [ 0 7 7 0 0 ] 0 1.226: Deoptimize [ 12 0 0 ] [ 0 0 0 0 0 ] 0 1.326: Deoptimize [ 12 0 0 ] [ 0 0 0 0 0 ] 0 1.399: Deoptimize [ 12 0 0 ] [ 0 0 0 0 0 ] 0 1.497: Deoptimize [ 12 0 0 ] [ 0 0 0 0 0 ] 0 2.409: G1IncCollectionPause [ 12 0 0 ] [ 0 0 0 0 4 ] 0 2.417: CGC_Operation [ 12 0 1 ] [ 0 1 1 0 5 ] 0 2.425: CGC_Operation [ 12 0 1 ] [ 0 4 4 0 1 ] 0 3.431: no vm operation [ 12 0 1 ] [ 0 17 17 0 0 ] 0 3.885: G1IncCollectionPause [ 12 0 0 ] [ 0 0 0 0 2 ] 0 3.888: G1CollectForAllocation [ 12 0 0 ] [ 0 0 0 0 86 ] 0 4.037: Exit [ 12 0 1 ] [ 0 0 0 0 339 ] 0 Polling page always armed Deoptimize 4 CGC_Operation 2 G1CollectForAllocation 1 G1IncCollectionPause 2 Exit 1 0 VM operations coalesced during safepoint Maximum sync time 17 ms Maximum vm operation time (except for Exit VM operation) 86 ms SymbolTable statistics: Number of buckets : 20011 = 160088 bytes, avg 8.000 Number of entries : 22112 = 530688 bytes, avg 24.000 Number of literals : 22112 = 932040 bytes, avg 42.151 Total footprint : = 1622816 bytes Average bucket size : 1.105 Variance of bucket size : 1.111 Std. dev. of bucket size: 1.054 Maximum bucket size : 8 StringTable statistics: Number of buckets : 60013 = 480104 bytes, avg 8.000 Number of entries : 2944 = 70656 bytes, avg 24.000 Number of literals : 2944 = 238320 bytes, avg 80.951 Total footprint : = 789080 bytes Average bucket size : 0.049 Variance of bucket size : 0.049 Std. dev. of bucket size: 0.222 Maximum bucket size : 3