垃圾回收器——CMS与G1

查看JVM所有的参数及默认值

java -XX:+PrintFlagsFinal

什么是垃圾回收,为什么要有垃圾回收

这是R大关于做菜与洗碗的思考,真的浅显易懂。
首先,一般来说(除非手动调用unsafe或者使用DirectByteBuffer)Java是自动分配和回收内存的,既然有分配机制,自然就得有回收机制,不然多大的家产也得败光。内存的回收机制也就是垃圾回收了。自动分配内存的方式有好处也有坏处,坏处就是我们常说的GC了,好处就是自动了。
Java的GC算法在早期时采用的是引用计数法,现在使用的是根可达算法。

传统意义上说,引用计数法不能解决循环引用的问题,但是,实际上是可以解决循环引用的问题

根可达中的根

链接: 官方说明GCRoots有哪些,一般来说比较常见的是

  1. 线程栈变量(存储在栈帧的局部变量表中的对象或引用)
  2. 静态变量 方法区中类静态属性引用的对象
  3. 常量池 方法区中常量引用的对象
  4. JNI指针本地方法栈中JNI(即一般说的native方法)中引用的对象

安全点与安全区间

GC并不是可以在任意时刻进行的,当JVM认为需要进行GC时,并不是突兀的直接停止所有的线程,而是给业务线程发出消息,业务线程会在安全点或安全区间阻塞下来(这时就发生了stop the word)。
关于SafePotin、Safe Region可以看下R大在知乎的解答RednaxelaFX对安全点的解释
之前听到过有人这么理解安全点:

有一天妈妈发现屋里太脏了,需要打扫屋子,这时妈妈进屋子说,赶紧准备一下,我要收拾屋子了。然后我磨蹭了一下,放下了手里的花生、瓜子,走出了屋子。然后妈妈就开始收拾屋子了。
又有一天,妈妈又发现屋里太脏了,这时妈妈一进屋,发现我正在睡觉,然后妈妈就直接收拾屋子了

上面这两个例子中就体现了JVM(妈妈)、业务线程(垃圾制造者,我)、安全点(我放下手里的东西后),安全区间(我正在睡觉)

内存分代划分,为什么要有内存分代划分

一般来说,在JVM中大部分的对象都是朝生夕死的,他们的一生相当的短暂,比如各种vo、dto之类的。但是同时,也存在少量对象需要长期存活,比如某些缓存对象。
由于GC有三大基本算法

  1. 标记复制
  2. 标记清除
  3. 标记整理

然后就有了分代的说法,将JVM的堆空间划分为年轻代(eden+survivor0+survivor1)和年老代。不同的分代采用不同的GC策略

jstat

一般我们采用jstat -gcutil pid 1000来观察系统的GC情况,通过jstat我们可以对系统的GC有一个粗略的了解

CMS垃圾回收器

参考文档简书CMS垃圾收集器

CMS是基于标记清除算法并行老年代垃圾收集器,可以通过参数-XX:+UseConcMarkSweepGC来启用CMS垃圾回收器。在JDK1.8下,当你启用CMS垃圾回收时,年轻代默认采用UseParNewGC,官方文档说明如下:
UseConcMarkSweepGC

CMS的内存分代划分

在CMS垃圾回收器中,依旧是经典的年轻代+年老代内存划分

CMS工作流程

CMS工作流程

初始标记

标记出所有的GCRoots,这步会导致stop the word,这里的GCRoots包含两部分:

  1. 年老代中的GCRoots对象
  2. 年轻代中活着的对象引用到的年老代的对象

并发标记

从GCRoots开始,对堆中的对象进行可达性分析,标记出存活对象,这步会跟用户线程并行执行,耗时比较长,但是没有停顿。由于是并发执行,所以这一步是有可能出现concurrent mode failure

重新标记

重新标记的任务是标记出所有年老代存活的对象。需要stop the word。同时,这一步扫描的范围是整个堆。为什么为了标记出年老代所有存活的对象需要扫描整个堆空间呢?原因很简单,因为可能存在年轻代的对象引用了年老代对象的场景。一般来说这一步不会很久,但是,如果这步的耗时比较长,那么可以设置参数-XX:+CMSScavengeBeforeRemark来让CMS重新标记前触发一下YGC,试年轻代变小从而提升重新标记的速度。
PS:网上也有说设置-XX:+CMSParallelRemarkEnabled的,这个参数在JDK1.8的官方文档里并没有搜索到,然后通过PrintFlagsFinal查看了一下,发现确实有这个参数,但是默认值就是true,所以不需要额外设置
在这里插入图片描述

并发清理

清理垃圾对象,这个操作与用户线程并行执行。浮动垃圾就是在这个时候产生的。由于并发清理阶段用户线程还在运行,所以CMS没法处理在这一阶段产生的垃圾,这些垃圾就被成为浮动垃圾。

CMS注意事项

优点:

  1. 并发收集
  2. 低停顿

缺点

  1. CPU敏感
  2. 无法处理浮动垃圾
  3. 存在内存碎片
    因为CMS基于标记-清除算法的,所以必然存在内存碎片的问题。但是JVM提供了-XX:CMSFullGCsBeforeCompaction=n来解决这个问题,其中CMSFullGCsBeforeCompaction的默认值就是0,也就是只要CMS遇到Full GC时,就会执行内存压缩,这样就补救了空间碎片的问题。
  4. concurrent mode failure
    并行失败,因为并行标记期间,用户线程依然在运行,只要运行就可能产生垃圾。当年轻代满了时,就会触发YGC,这时有些对象可能需要被存到到年老代中,但是,年老代没有大小合适且连续的空间存放这些对象,就引发了这个问题。可以通过设置-XX:CMSInitiatingOccupancyFraction=percent-XX:+UseCMSInitiatingOccupancyOnly来提前CMS。因为CMS是一款并行年老代垃圾回收器,所以不能等年老代全部用完再执行垃圾回收,一定要提早进行垃圾回收以避免出现这个问题。但是也要慎重XX:CMSInitiatingOccupancyFraction越大,越可能出现concurrent mode failure,越小,CMS频率就越高

参数调优

参数说明
-XX:+UseConcMarkSweepGC使用CMS垃圾回收器
-XX:+CMSScavengeBeforeRemark在重新标记前先执行一次YGC,提升重新标记的效率
-XX:CMSFullGCsBeforeCompaction=nCMS进行n次Full GC之后,执行碎片压缩,默认值是0,也就是每次Full GC之后都会进行内存压缩,一般不需要配置
-XX:ParallelGCThreads=threads垃圾回收器可用的线程数
-XX:CMSInitiatingOccupancyFraction=percent当年老代的使用率达到percent%时CMS开始回收垃圾
-XX:+UseCMSInitiatingOccupancyOnly使用设置的值替代JVM的默认值

流言终结者

-XX:+UseCMSCompactAtFullCollection 默认值就是true,不需要设置
-XX:+CMSParallelRemarkEnabled 默认值就是true,不需要设置
-XX:+CMSIncrementalMode 增量式CMS,JDK1.8已经明确说明不赞成使用

适用场景

个人认为在堆不太大时(<6G)都可以使用CMS垃圾回收器。

日志分析

代码样例:

/**
 * -Xms10m -Xmn1m -Xmx10m -XX:+PrintGCDetails -XX:+UseConcMarkSweepGC 
 * -XX:CMSInitiatingOccupancyFraction=40 -XX:+UseCMSInitiatingOccupancyOnly
 */
public class CMSTest {
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        while (true){
            byte[] bytes = new byte[1024*100];
            list.add(bytes);
        }
    }
}

GC日志:

[GC (Allocation Failure) [ParNew: 896K->64K(960K), 0.0026215 secs] 896K->604K(10176K), 0.0026863 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 960K->63K(960K), 0.0007438 secs] 1500K->819K(10176K), 0.0007669 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 880K->63K(960K), 0.0005982 secs] 1636K->1189K(10176K), 0.0006230 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 890K->9K(960K), 0.0010412 secs] 2017K->1978K(10176K), 0.0010611 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 832K->6K(960K), 0.0006470 secs] 2802K->2775K(10176K), 0.0006661 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 822K->6K(960K), 0.0010917 secs] 3592K->3575K(10176K), 0.0011130 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 838K->12K(960K), 0.0006579 secs] 4408K->4382K(10176K), 0.0006773 secs] [Times: user=0.14 sys=0.02, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 829K->6K(960K), 0.0006898 secs] 5199K->5176K(10176K), 0.0007088 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//CMS初始标记
[GC (CMS Initial Mark) [1 CMS-initial-mark: 5170K(9216K)] 5496K(10176K), 0.0008488 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//CMS并行标记开始
[CMS-concurrent-mark-start]
[GC (Allocation Failure) [ParNew: 826K->10K(960K), 0.0008180 secs] 5996K->5980K(10176K), 0.0008409 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 829K->8K(960K), 0.0006254 secs] 6800K->6778K(10176K), 0.0006511 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 827K->12K(960K), 0.0007963 secs] 7598K->7582K(10176K), 0.0008136 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 831K->14K(960K), 0.0007207 secs] 8402K->8385K(10176K), 0.0007405 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
// 这里发生了年轻代晋升到老年的晋升失败
[GC (Allocation Failure) [ParNew (promotion failed): 843K->837K(960K), 0.0003956 secs][CMS[CMS-concurrent-mark: 0.001/0.008 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
 (concurrent mode failure): 8470K->9048K(9216K), 0.0063871 secs] 9213K->9048K(10176K), [Metaspace: 3189K->3189K(1056768K)], 0.0068362 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [ParNew: 817K->817K(960K), 0.0000104 secs][CMS: 9048K->9148K(9216K), 0.0015853 secs] 9866K->9849K(10176K), [Metaspace: 3189K->3189K(1056768K)], 0.0016326 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//导致了这里的FGC
[Full GC (Allocation Failure) [CMS: 9148K->9131K(9216K), 0.0021235 secs] 9949K->9931K(10176K), [Metaspace: 3189K->3189K(1056768K)], 0.0021494 secs] [Times: user=0.02 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [CMS: 9131K->9131K(9216K), 0.0013697 secs] 9931K->9931K(10176K), [Metaspace: 3189K->3189K(1056768K)], 0.0013915 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (CMS Initial Mark) [1 CMS-initial-mark: 9131K(9216K)] 9951K(10176K), 0.0005096 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[CMS-concurrent-mark-start]
[CMS-concurrent-mark: 0.001/0.001 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//CMS预清理开始
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
//一般来说需要关注一下这个,这个是重新标记,如果时间过长,那应该需要做参数调整
[GC (CMS Final Remark) [YG occupancy: 877 K (960 K)][Rescan (parallel) , 0.0002254 secs][weak refs processing, 0.0000174 secs][class unloading, 0.0001532 secs][scrub symbol table, 0.0003007 secs][scrub string table, 0.0000816 secs][1 CMS-remark: 9131K(9216K)] 10009K(10176K), 0.0008232 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[CMS-concurrent-sweep-start]
Heap
 par new generation   total 960K, used 895K [0x00000000ff600000, 0x00000000ff700000, 0x00000000ff700000)
  eden space 896K,  99% used [0x00000000ff600000, 0x00000000ff6dfcc0, 0x00000000ff6e0000)
  from space 64K,   0% used [0x00000000ff6f0000, 0x00000000ff6f0000, 0x00000000ff700000)
  to   space 64K,   0% used [0x00000000ff6e0000, 0x00000000ff6e0000, 0x00000000ff6f0000)
 concurrent mark-sweep generation total 9216K, used 8828K [0x00000000ff700000, 0x0000000100000000, 0x0000000100000000)
 Metaspace       used 3266K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 356K, capacity 388K, committed 512K, reserved 1048576K
[CMS-concurrent-sweep: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[CMS-concurrent-reset-start]
//最后内存溢出了,这个本来就是一个死循环
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at com.example.gc.CMSTest.main(CMSTest.java:12)

Process finished with exit code 1

G1垃圾回收器

参考文章R大对G1的解释
参考文章美团:Java Hotspot G1 GC的一些关键技术
参考文章官方文档
G1,garbage-first。是一个跟以往完全不同的垃圾回收器。与CMS不同的是G1回收不仅仅回收老年代(mixed gc),也会回收年轻代(young gc),同时,G1不能想CMS一样完全回收老年代。G1如果出现问题,最后会退化为Serial old GC。

G1的内存分代划分

G1在逻辑概念上依然保留了年轻代和年老代的概念,但实际上是将内存划分为了多个Region,如下图所示:
在这里插入图片描述
每个Region从存储内容上又可以划分为Eden、Survivor、Old和Humongous。其中Humongous是G1引入的新的概念,意思是巨大对象(每个巨大对象至少要有Region一半的大小),Humongous在逻辑上是属于Old的。相当于提前晋级,省去了反复拷贝的工作。
按照Region来划分内存还带来了其他的好处,比如垃圾回收时,也是按照Region的粒度来做回收,这也就使得G1可以预测GC的时间。再比如,当某些处于Survivor区域的对象需要晋升到Old时,G1可以直接标记S为O,这样可以在极快的速度内完成对象的晋升;如果某些Eden中的对象不再被需要,那么G1也可以直接格式化这个Region。可以使用-XX:G1HeapRegionSize=size来设定单个Region的大小,官方的解释说明如下:

-XX:G1HeapRegionSize=size
Sets the size of the regions into which the Java heap is subdivided when using the garbage-first (G1) collector. The value can be between 1 MB and 32 MB. The default region size is determined ergonomically based on the heap size.
The following example shows how to set the size of the subdivisions to 16 MB:
-XX:G1HeapRegionSize=16m

G1 Young GC

选定所有年轻代里的Region。通过控制年轻代的Region个数,即年轻代内存大小,来控制young GC的时间开销,YoungGC时会有一次stop the word,回收完毕后,被回收的Region被清空,存活的对象晋升到Survivor,年龄达标的对象晋升到Old

G1 Mixed GC

选定所有年轻代里的Region,外加根据global concurrent marking统计得出收集收益高的若干老年代Region。在用户指定的开销目标范围内尽可能选择收益高的老年代Region。
在这里插入图片描述
MixedGC也是分为4个步骤

初始标记

标记了从GC Root开始直接可达的对象,这个阶段共用了Young GC的暂停,这是因为他们可以复用root scan操作,所以可以说global concurrent marking是伴随Young GC而发生的。这个阶段是需要stop the word的。

并发标记

这个解读那从GC Roots开始对heap中的对象标记,标记线程与应用程序线程并行执行,同时收集各个Region的存活对象信息。这里与CMS不同的是,G1在并发标记过程中使用了SATB来解决并发问题,但是CMS使用的是增量更新和写屏障。在效率上G1更好,但是在内存的使用上CMS更低。

最终标记

这里依然需要stop the word,用于标记并发标记阶段结束后仍然有引用变动的对象。

垃圾清除

根据标记的可达对象,更新Region的统计数据,对各个Region的回收价值和成本进行排序,根据用户设置的JVM暂停时间定制回收计划,决定回收的那一部分Region的存活对象被复制到空的Region中,再清理掉整个旧的Region的全部空间。这个过程涉及到了存活对象的复制,需要stop the word

G1的优点和缺点

G1从整体来看是基于标记—清除算法的,但是局部又是标记—复制。这种特性导致G1并不会产生浮动垃圾,但是CMS会。
G1因为需要使用Rset和SATB所以相比CMS需要更多的内存来承载这些东西,在内存的占用上更高,所以官方也是建议至少要大于6G才可以使用G1
在这里插入图片描述

参数调优

参数说明
-XX:+UseG1GC使用G1垃圾回收器
-XX:G1HeapRegionSize=size设置Region大小,并非最终值
-XX:MaxGCPauseMillis=time设置G1收集过程目标时间,默认值200ms,不是硬性条件。设置的时间越短意味着每次收集的CSet越小,导致垃圾逐步积累变多,最终不得不退化成 Serial GC;停顿时间设置的过长那么会导致每次都会产生长时间的停顿影响了程序对外的响应时间。低延迟的系统这个值可以略微设置的高一点,比如500
-XX:ParallelGCThreads=threads垃圾回收器可用的线程数
-XX:ConcGCThreads=threads并发标记阶段可用的线程数
-XX:InitiatingHeapOccupancyPercent=percentSets the percentage of the heap occupancy (0 to 100) at which to start a concurrent GC cycle. It is used by garbage collectors that trigger a concurrent GC cycle based on the occupancy of the entire heap, not just one of the generations (for example, the G1 garbage collector).By default, the initiating value is set to 45%. A value of 0 implies nonstop GC cycles.

流言终结者

下面这两个参数并不是可以直接使用的,必须先使用-XX:+UnlockExperimentalVMOptions之后才可以使用

  1. -XX:G1NewSizePercent=n
  2. -XX:G1MaxNewSizePercent=n

官方建议

连接
Recommendations
When you evaluate and fine-tune G1 GC, keep the following recommendations in mind:

  1. Young Generation Size: Avoid explicitly setting young generation size with the -Xmn option or any or other related option such as -XX:NewRatio. Fixing the size of the young generation overrides the target pause-time goal.

  2. Pause Time Goals: When you evaluate or tune any garbage collection, there is always a latency versus throughput trade-off. The G1 GC is an incremental garbage collector with uniform pauses, but also more overhead on the application threads. The throughput goal for the G1 GC is 90 percent application time and 10 percent garbage collection time. Compare this to the Java HotSpot VM parallel collector. The throughput goal of the parallel collector is 99 percent application time and 1 percent garbage collection time. Therefore, when you evaluate the G1 GC for throughput, relax your pause time target. Setting too aggressive a goal indicates that you are willing to bear an increase in garbage collection overhead, which has a direct effect on throughput. When you evaluate the G1 GC for latency, you set your desired (soft) real-time goal, and the G1 GC will try to meet it. As a side effect, throughput may suffer. See the section Pause Time Goal in Garbage-First Garbage Collector for additional information.

  3. Taming Mixed Garbage Collections: Experiment with the following options when you tune mixed garbage collections. See the section Important Defaults for information about these options:

    1. -XX:InitiatingHeapOccupancyPercent: Use to change the marking threshold.
    2. -XX:G1MixedGCLiveThresholdPercent and -XX:G1HeapWastePercent: Use to change the mixed garbage collection decisions.
    3. -XX:G1MixedGCCountTarget and -XX:G1OldCSetRegionThresholdPercent: Use to adjust the CSet for old regions.

日志分析

/**
 * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+UseG1GC -XX:+PrintGCDateStamps
 */
public class G1Test {
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>(1);
        while (true){
            byte[] bytes = new byte[1024*100];
            list.add(bytes);
        }
    }
}

GC日志

2021-08-02T22:16:23.710+0800: [GC pause (G1 Evacuation Pause) (young) (to-space exhausted), 0.0037248 secs]
   [Parallel Time: 1.7 ms, GC Workers: 10]
      [GC Worker Start (ms): Min: 169.0, Avg: 169.1, Max: 169.4, Diff: 0.4]
      [Ext Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.3, Diff: 0.3, 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.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 0.5, Avg: 0.8, Max: 0.9, Diff: 0.4, Sum: 8.0]
      [Termination (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 0.8]
         [Termination Attempts: Min: 1, Avg: 5.3, Max: 9, Diff: 8, Sum: 53]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.3]
      [GC Worker Total (ms): Min: 0.7, Avg: 1.0, Max: 1.1, Diff: 0.4, Sum: 10.4]
      [GC Worker End (ms): Min: 170.2, Avg: 170.2, Max: 170.2, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.4 ms]
   [Other: 1.6 ms]
      [Evacuation Failure: 0.7 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.6 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.2 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 6144.0K(6144.0K)->0.0B(1024.0K) Survivors: 0.0B->1024.0K Heap: 6144.0K(10.0M)->9216.0K(10.0M)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-08-02T22:16:23.715+0800: [GC pause (G1 Evacuation Pause) (young) (initial-mark) (to-space exhausted), 0.0032400 secs]
   [Parallel Time: 2.0 ms, GC Workers: 10]
      [GC Worker Start (ms): Min: 173.3, Avg: 173.3, Max: 173.4, Diff: 0.1]
      [Ext Root Scanning (ms): Min: 1.5, Avg: 1.6, Max: 1.6, Diff: 0.1, Sum: 15.6]
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.2, Diff: 0.2, Sum: 0.4]
         [Processed Buffers: Min: 0, Avg: 1.4, Max: 11, Diff: 11, Sum: 14]
      [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.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 0.2, Avg: 0.2, Max: 0.3, Diff: 0.1, Sum: 2.3]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.4]
         [Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 10]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
      [GC Worker Total (ms): Min: 1.8, Avg: 1.9, Max: 1.9, Diff: 0.1, Sum: 18.7]
      [GC Worker End (ms): Min: 175.2, Avg: 175.2, Max: 175.2, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.2 ms]
   [Other: 1.0 ms]
      [Evacuation Failure: 0.6 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.1 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.2 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 1024.0K(1024.0K)->0.0B(1024.0K) Survivors: 1024.0K->0.0B Heap: 10.0M(10.0M)->10.0M(10.0M)]
 [Times: user=0.02 sys=0.00, real=0.00 secs] 
2021-08-02T22:16:23.718+0800: [GC concurrent-root-region-scan-start]
2021-08-02T22:16:23.718+0800: [GC concurrent-root-region-scan-end, 0.0000156 secs]
2021-08-02T22:16:23.718+0800: [GC concurrent-mark-start]
2021-08-02T22:16:23.718+0800: [GC pause (G1 Evacuation Pause) (young), 0.0011984 secs]
   [Parallel Time: 0.6 ms, GC Workers: 10]
      [GC Worker Start (ms): Min: 176.7, Avg: 176.7, Max: 176.8, Diff: 0.1]
      [Ext Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.7]
      [Update RS (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 1.0]
         [Processed Buffers: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 10]
      [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.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Termination (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 1.3]
         [Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 10]
      [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.3, Avg: 0.3, Max: 0.3, Diff: 0.1, Sum: 3.1]
      [GC Worker End (ms): Min: 177.0, Avg: 177.0, Max: 177.0, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.2 ms]
   [Other: 0.4 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.2 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.2 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 0.0B(1024.0K)->0.0B(1024.0K) Survivors: 0.0B->0.0B Heap: 10.0M(10.0M)->10.0M(10.0M)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-08-02T22:16:23.720+0800: [GC pause (G1 Evacuation Pause) (young), 0.0015950 secs]
   [Parallel Time: 0.5 ms, GC Workers: 10]
      [GC Worker Start (ms): Min: 178.2, Avg: 178.3, Max: 178.3, Diff: 0.1]
      [Ext Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.6]
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
         [Processed Buffers: Min: 0, Avg: 0.1, Max: 1, Diff: 1, Sum: 1]
      [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.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
         [Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 10]
      [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.1, Max: 0.1, Diff: 0.1, Sum: 0.9]
      [GC Worker End (ms): Min: 178.4, Avg: 178.4, Max: 178.4, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.4 ms]
   [Other: 0.7 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.3 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.4 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 0.0B(1024.0K)->0.0B(1024.0K) Survivors: 0.0B->0.0B Heap: 10.0M(10.0M)->10.0M(10.0M)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-08-02T22:16:23.721+0800: [Full GC (Allocation Failure)  10M->5301K(10M), 0.0025288 secs]
   [Eden: 0.0B(1024.0K)->0.0B(1024.0K) Survivors: 0.0B->0.0B Heap: 10.0M(10.0M)->5301.3K(10.0M)], [Metaspace: 3298K->3298K(1056768K)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-08-02T22:16:23.724+0800: [GC concurrent-mark-abort]
2021-08-02T22:16:23.724+0800: [GC pause (G1 Evacuation Pause) (young), 0.0009866 secs]
   [Parallel Time: 0.2 ms, GC Workers: 10]
      [GC Worker Start (ms): Min: 182.9, Avg: 182.9, Max: 183.0, Diff: 0.1]
      [Ext Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.7]
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
         [Processed Buffers: Min: 0, Avg: 0.2, Max: 1, Diff: 1, Sum: 2]
      [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.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.2]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
         [Termination Attempts: Min: 1, Avg: 1.2, Max: 2, Diff: 1, Sum: 12]
      [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.1, Avg: 0.1, Max: 0.2, Diff: 0.1, Sum: 1.1]
      [GC Worker End (ms): Min: 183.0, Avg: 183.0, Max: 183.0, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.3 ms]
   [Other: 0.5 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.4 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.1 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 1024.0K(1024.0K)->0.0B(1024.0K) Survivors: 0.0B->1024.0K Heap: 6325.3K(10.0M)->6205.4K(10.0M)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-08-02T22:16:23.726+0800: [GC pause (G1 Evacuation Pause) (young) (initial-mark), 0.0010026 secs]
   [Parallel Time: 0.4 ms, GC Workers: 10]
      [GC Worker Start (ms): Min: 184.1, Avg: 184.2, Max: 184.3, Diff: 0.1]
      [Ext Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 1.2]
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
         [Processed Buffers: Min: 0, Avg: 0.4, Max: 2, Diff: 2, Sum: 4]
      [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.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.9]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.2]
         [Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 10]
      [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.1, Avg: 0.2, Max: 0.3, Diff: 0.1, Sum: 2.3]
      [GC Worker End (ms): Min: 184.4, Avg: 184.4, Max: 184.4, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.2 ms]
   [Other: 0.4 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.2 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.2 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 1024.0K(1024.0K)->0.0B(3072.0K) Survivors: 1024.0K->1024.0K Heap: 7229.4K(10.0M)->7206.3K(10.0M)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-08-02T22:16:23.727+0800: [GC concurrent-root-region-scan-start]
2021-08-02T22:16:23.727+0800: [GC concurrent-root-region-scan-end, 0.0001289 secs]
2021-08-02T22:16:23.727+0800: [GC concurrent-mark-start]
2021-08-02T22:16:23.727+0800: [GC pause (G1 Evacuation Pause) (young) (to-space exhausted), 0.0008391 secs]
   [Parallel Time: 0.3 ms, GC Workers: 10]
      [GC Worker Start (ms): Min: 185.5, Avg: 185.5, Max: 185.6, Diff: 0.1]
      [Ext Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.7]
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
         [Processed Buffers: Min: 0, Avg: 0.5, Max: 1, Diff: 1, Sum: 5]
      [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.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.6]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.4]
         [Termination Attempts: Min: 1, Avg: 1.4, Max: 2, Diff: 1, Sum: 14]
      [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.1, Avg: 0.2, Max: 0.2, Diff: 0.1, Sum: 1.8]
      [GC Worker End (ms): Min: 185.7, Avg: 185.7, Max: 185.7, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.1 ms]
   [Other: 0.4 ms]
      [Evacuation Failure: 0.1 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.1 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.1 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 2048.0K(3072.0K)->0.0B(3072.0K) Survivors: 1024.0K->0.0B Heap: 9254.3K(10.0M)->9373.8K(10.0M)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-08-02T22:16:23.728+0800: [Full GC (Allocation Failure)  9373K->9033K(10M), 0.0025119 secs]
   [Eden: 0.0B(3072.0K)->0.0B(1024.0K) Survivors: 0.0B->0.0B Heap: 9373.8K(10.0M)->9033.2K(10.0M)], [Metaspace: 3306K->3306K(1056768K)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-08-02T22:16:23.731+0800: [Full GC (Allocation Failure)  9033K->9033K(10M), 0.0019493 secs]
   [Eden: 0.0B(1024.0K)->0.0B(1024.0K) Survivors: 0.0B->0.0B Heap: 9033.2K(10.0M)->9033.2K(10.0M)], [Metaspace: 3306K->3306K(1056768K)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-08-02T22:16:23.733+0800: [GC concurrent-mark-abort]
2021-08-02T22:16:23.733+0800: [GC pause (G1 Evacuation Pause) (young), 0.0007437 secs]
   [Parallel Time: 0.2 ms, GC Workers: 10]
      [GC Worker Start (ms): Min: 191.3, Avg: 191.3, Max: 191.4, Diff: 0.1]
      [Ext Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.7]
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
         [Processed Buffers: Min: 0, Avg: 0.1, Max: 1, Diff: 1, Sum: 1]
      [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.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.3]
         [Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 10]
      [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.1, Max: 0.1, Diff: 0.1, Sum: 1.1]
      [GC Worker End (ms): Min: 191.5, Avg: 191.5, Max: 191.5, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.2 ms]
   [Other: 0.4 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.2 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.1 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 0.0B(1024.0K)->0.0B(2048.0K) Survivors: 0.0B->0.0B Heap: 9033.2K(10.0M)->9033.2K(10.0M)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-08-02T22:16:23.734+0800: [GC pause (G1 Evacuation Pause) (young), 0.0007566 secs]
   [Parallel Time: 0.2 ms, GC Workers: 10]
      [GC Worker Start (ms): Min: 192.3, Avg: 192.3, Max: 192.4, Diff: 0.1]
      [Ext Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.6]
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
         [Processed Buffers: Min: 0, Avg: 0.1, Max: 1, Diff: 1, Sum: 1]
      [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.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.2]
         [Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 10]
      [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.1, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.9]
      [GC Worker End (ms): Min: 192.4, Avg: 192.4, Max: 192.4, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.1 ms]
   [Other: 0.4 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.2 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.2 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 0.0B(2048.0K)->0.0B(2048.0K) Survivors: 0.0B->0.0B Heap: 9033.2K(10.0M)->9033.2K(10.0M)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
2021-08-02T22:16:23.735+0800: [Full GC (Allocation Failure)  9033K->730K(10M), 0.0024007 secs]
   [Eden: 0.0B(2048.0K)->0.0B(4096.0K) Survivors: 0.0B->0.0B Heap: 9033.2K(10.0M)->730.5K(10.0M)], [Metaspace: 3306K->3306K(1056768K)]
 [Times: user=0.00 sys=0.00, real=0.00 secs] 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at com.example.gc.G1Test.main(G1Test.java:14)
Heap
 garbage-first heap   total 10240K, used 730K [0x00000000ff600000, 0x00000000ff700050, 0x0000000100000000)
  region size 1024K, 1 young (1024K), 0 survivors (0K)
 Metaspace       used 3385K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 369K, capacity 388K, committed 512K, reserved 1048576K

Process finished with exit code 1

附录:JDK1.8参数默认值

JDK1.8参数默认值

附录 Example 1 - Tuning for Higher Throughput

java -d64 -server -XX:+AggressiveOpts -XX:+UseLargePages -Xmn10g  -Xms26g -Xmx26g

附录 Example 2 - Tuning for Lower Response Time

java -d64 -XX:+UseG1GC -Xms26g Xmx26g -XX:MaxGCPauseMillis=500 -XX:+PrintGCTimeStamp
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值