7

Java 虚拟机原理 (三) 垃圾收集

 3 years ago
source link: https://blog.duval.top/2021/01/09/Java-%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%8E%9F%E7%90%86-3-%E5%9E%83%E5%9C%BE%E6%94%B6%E9%9B%86/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Java 虚拟机技术是每个 Java 开发工程师都应该深入掌握的。本系列文章将深入介绍 JVM 相关技术,主要包括内存划分、对象创建回收与分配以及垃圾收集三大部分。本系列文章将力求全面概要地汇总核心知识点,并使知识点串联成面,以方便学习、工作以及备忘复习。本文将介绍第三部分——垃圾收集。

垃圾收集算法

  • 标记清除算法
    • 需要标记的对象非常多,效率一般不高
    • 内存容易导致空间碎片化问题
  • 标记整理算法
    • 在标记清除算法基础上,增加内存整理功能,避免碎片化的问题
    • 同样存在标记量大而效率不高的问题
  • 标记复制算法
    • 一般需要预留 Survivor 区域,导致空间利用率不高
    • 回收效率非常高
  • 分代收集算法
    • 常见的垃圾收集器都采用此法

常见垃圾收集器

经典垃圾收集器

  • 新生代收集器

    • Serial New 收集器(-XX:+UseSerialGC)

      新生代单线程垃圾收集器。

    • Parallel 收集器(-XX:+UseParallelGC):

      也称为 Parallel Scavenge收集器,可以理解为 Serial New 收集器的多线程版本。该垃圾收集器可与 Serial Old 以及 Parallel Old 两款收集器搭配使用。

    • ParNew 收集器(-XX:+UseParNewGC)

      该垃圾收集器专门开发来与 CMS 收集器搭配使用,当然也可以与 Serial Old 垃圾收集器使用。

  • 老年代收集器

    • Serial Old 收集器(-XX:+UseSerialOldGC)
    • Parallel Old 收集器(-XX:+UseParallelOldGC)

      老年代并行垃圾收集器,仅与 Parallel 收集器搭配使用。

    • CMS 收集器(-XX:+UseConcMarkSweepGC)
  • 跨代收集器

    • G1 收集器(-XX:+UseG1GC)

注意,在 jdk1.8.0_161 中测试发现 -XX:+UseSerialOldGC 参数已经不可用。目前各个垃圾收集器之间的关系图如下:
垃圾收集器之间的关系.png

垃圾收集器之间的关系.png


其中标红线表示 jdk1.8.0_161 之后推荐使用的搭配关系,此外 CMS 在并发失败的时候还会退化为 Serial Old。
从 JDK 源码也可以看出端倪:
check_gc_args

check_gc_args

CMS 垃圾收集器

CMS (Concurrent Mark Sweep)是老年代垃圾收集器,内部使用标记清除算法。其一般与 ParNew 搭配使用,回收过程一般划分为以下几个阶段:

CMS垃圾收集器回收阶段.png

CMS垃圾收集器回收阶段.png

  • 初始标记:快速标记 GC Roots 直接引用的对象,该阶段为 Stop The World 过程;
  • 并发标记:从 GC Roots 直接引用对象出发遍历其他存活对象,该过程与用户线程并发运行,因此可能会有已被标记的对象状态发生变化。该过程持续时间会比较长,但不会 STW;
  • 重新标记:修正并发标记阶段状态发生变动的对象,该阶段停顿时间会比初始标记稍长,但远比并发标记要短暂。另外,CMS 主要采用了三色标记的增量更新算法实现重新标记;
  • 并发清理:清理未标记的对象,该阶段与用户线程并发运行。同时根据三色标记原理,该阶段新增对象都会被标记为黑色而不必清理。

CMS 存在几个缺点:

  • 对 CPU 资源敏感,会与应用程序争抢 CPU 资源;
  • 并发标记和并发清理阶段会产生浮动垃圾,需要等待下一次 GC 过程才能回收;
  • 标记清除算法会产生大量空间碎片(但可通过 -XX:+UseCMSCompactAtFullCollection 参数让 JVM 清理后进行内存整理);
  • 在并发标记和并发清理阶段,GC 线程与用户线程并发执行,此时如果再次触发 Full GC,会引起 “concurrent mode failure”,此时会进入 STW 状态,并退化为使用 Serial Old 垃圾收集器来回收。

常用调优参数:

参数 参数含义 默认值 -XX:+UseConcMarkSweepGC 启用 CMS 收集器 默认搭配 ParNew 新生代收集器 -XX:ConcGCThreads 并发的 GC 线程数量 默认值(CPU核心数+3)/ 4 -XX:+UseCMSCompactAtFullCollection Full GC 后做压缩整理以减少内存碎片

-XX:CMSFullGCsBeforeCompaction 指定多少次 Full GC 后压缩整理一次 默认值是0,表示每次 Full GC 都会压缩一次 -XX:CMSInitiatingOccupancyFraction 当老年代使用达到该比例会触发 Full GC 默认值92(百分比) -XX:+ 表示仅使用设定的回收阈值(这里指CMSInitiatingOccupancyFraction),如果不指定,JVM仅在第一次使用设定阈值,后续则自动调整,所以一般设置了回收阈值都会同时设置该值。

-XX:+CMSScavengeBeforeRemark 在 Full GC 前执行一次 Minor GC,目的是减少老年代对年轻代的引用,从而降低标记阶段的开销

-XX:+CMSParallelInitialMarkEnabled 表示在初始标记的时候多线程执行从而缩短 STW

-XX:+CMSParallelRemarkEnabled 表示在重新标记的时候多线程执行从而缩短 STW 默认开启

GC 日志案例:

运行参数: -Xms50m -Xmx50m -XX:+UseConcMarkSweepGC -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128M -XX:+PrintGCDetails -XX:CMSInitiatingOccupancyFraction=92 -XX:+UseCMSInitiatingOccupancyOnly

## 初始标记
[GC (CMS Initial Mark) [1 CMS-initial-mark: 30614K(34176K)] 34916K(49536K), 0.0015545 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
## 并发标记
[CMS-concurrent-mark-start]
[CMS-concurrent-mark: 0.014/0.014 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[CMS-concurrent-abortable-preclean-start]
[CMS-concurrent-abortable-preclean: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
## 重新标记(最终标记)
[GC (CMS Final Remark) [YG occupancy: 4302 K (15360 K)][Rescan (parallel) , 0.0008078 secs][weak refs processing, 0.0004334 secs][class unloading, 0.0038316 secs][scrub symbol table, 0.0038272 secs][scrub string table, 0.0003411 secs][1 CMS-remark: 30614K(34176K)] 34916K(49536K), 0.0093542 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
## 并发清理
[CMS-concurrent-sweep-start]
[CMS-concurrent-sweep: 0.003/0.003 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
## 并发重置
[CMS-concurrent-reset-start]
[CMS-concurrent-reset: 0.000/0.000 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

主要看点:

  • 初始标记耗时非常短(0.0015545 secs),触发阈值约是90%(30614/34176≈90%),这值比参数指定值92%略小,但在预期之内;
  • 并发标记阶段不会 STW,用时相对较长(0.014 secs);
  • 重新标记阶段默认就是多线程(Rescan (parallel)),也就是说 CMSParallelRemarkEnabled 默认开启;

G1 垃圾收集器

G1 垃圾收集器与 CMS 收集器非常相似,但存在本质的区别。读者可以先看下一篇《Java 虚拟机原理 (四) G1垃圾收集器入门》进行了解,此处不再重复。

下边直接来看 G1 的垃圾回收阶段图:

G1垃圾收集阶段图.png

G1垃圾收集阶段图.png

具体各个阶段总结如下:

回收阶段 是否 STW 过程 年轻代收集 (young gc) 是(收集过程中复制移动动作是一个 STW 过程) 1.使用复制算法,从 eden 区将存活对象转移到 survivor区;
2.如果对象超过了老化阈值,则会被晋升到老年代区块中。 初始标记(initial-mark) 是 1.当老年代占堆比重达到 IHOP 阈值(缺省45%),则会触发并发标记周期,并进入初始标记阶段;
2.初始标记过程是伴随着一次年轻代收集同时完成的;
3.该过程主要是标记那些引用了老年代对象的 Survivor 区块(也就是根区块) 并发根区块扫描 (concurrent-root-scan) 否 1.扫描那些引用了老年代的 Suvivor 区块(根区块)并标记他们所引用的对象。
2.这个阶段是和应用线程并行执行。这个阶段必须在下一次 young gc 发生之前完成。 并发标记 (concurrent-mark) 否 1.在全堆范围内寻找存活对象;
2.该过程与应用线程并行执行;
3.这个阶段可以被年轻代垃圾收集过程所打断(也就是中间可以穿插多个 young gc) 重新标记 (remark) 是 1.最终完成堆中所有存活对象的标记;
2.这个阶段使用了一个叫SATB(snapshot-at-the-beginning)的算法,该算法比CMS收集器所用算法快非常多。 并发清理 (cleanup) 是(重置空区块阶段(3)为并发操作) 1.清算存活对象以及空区块 (STW);
2.擦除 RSets (STW);
3.重置空区块,并添加进空闲区块列表;4.该阶段还会决定是否进入空间回收周期。 空间回收周期(space reclamation 是 1.该过程会疏散或者复制存活对象那到新的未使用区块上;
2.这过程可以包含多次 young gc,可以发生在年轻代区块中,GC日志中显示为[GC pause (young)],或者同时发生在年轻代和老年代区块中,而GC日志中显示为[GC Pause (mixed)];
3.当G1判断不再值得回收老年代区块以获取更多空间的时候,便会结束该阶段,并进入下一个年轻代收集循环。

注意!当 G1 在回收存活对象或者是晋升对象到老年代的时候发生堆空间不足,将会触发晋升失败。此时,G1将进入 STW,并使用单线程来进行 Full GC。如果调优到位的话,你的应用应该避免Full GC发生。

综上,G1 垃圾收集模式分为三种:

  • Young GC:当 G1 评估当前年轻代的回收时间接近 -XX:MaxGCPauseMillis 指定值的时候,会触发 Young GC;
  • Mixed GC:当 老年代占有率达到 -XX:InitiatingHeapOccupancyPercent 指定值的时候,会触发并发周期。而并发清理阶段阶段会判断是否需要进入空间回收周期。在空间回收周期内,会根据期望的GC停顿时间以及区块的回收价值等来决定是否进行以及进行多少次 Mixed GC;
  • Full GC:STW,单线程收集过程。

常用调优参数:

参数 参数含义 默认值 -XX:+UseG1GC 指定使用 G1 垃圾收集器

-XX:MaxGCPauseMillis=200 设定一个最大的GC停顿时间目标。这是一个软目标,JVM会尽最大努力满足这个目标。但不宜设置过小,以免因为每次回收垃圾过少而导致频繁 GC。 200 (ms) -XX:GCPauseTimeInterval=<ergo> GC 停顿间隔时间 G1 在默认情况下不设置该值,而允许G1在一些极端的情况下连续执行垃圾回收 -XX:ParallelGCThreads=<ergo> 并行阶段最大的线程数 根据CPU核心数N进行计算,如果N<8,那么ParallelGCThreads=N;如果N>=8,那么ParallelGCThreads=N*5/8 -XX:ConcGCThreads=<ergo> 并发阶段最大的线程数 默认值是-XX:ParallelGCThreads的值除以4 -XX:+G1UseAdaptiveIHOP
-XX:InitiatingHeapOccupancyPercent=45 配置启用IHOP,以及配置触发比例 默认启用,触发比例为45% -XX:G1HeapRegionSize=<ergo> 设置区块大小 整个堆最多划分为2048个Region,Region的大小一定是在1~32M之间,并且是2的N次方。 所以,如果堆的尺寸小于2G,那么Region数量就会少于2048。如果设置的堆大于64G,JVM会适当增加region的数量,但是region大小一定不会超过32M。 -XX:G1NewSizePercent=5
-XX:G1MaxNewSizePercent=60 配置年轻代占比 最小值默认为5%,最大值默认为60% -XX:G1HeapWastePercent=5 允许浪费的堆内存比例。如果可回收百分比低于这个百分比,那么G1就不会触发Mixed GC。 默认值5% -XX:G1MixedGCCountTarget=8 设置空间清理阶段的回收次数 默认不超过8次 -XX:G1MixedGCLiveThresholdPercent=85 如果老年代区块内部存活对象超过该比例,那么在空间清理阶段不会将该区块加入 CSet,也就是不会对其进行回收 默认值85% -XX:G1ReservePercent=10 设置堆的保留空间阈值以降低发生晋升失败的可能。 默认值是10 -XX:G1OldCSetRegionThresholdPercent=10 设置Mixed GC期间要回收的老年代Region数量上限,即一次Mixed GC中最多可以被选入CSet中的老年代Region数量。 默认值10%

GC 日志案例:

  • CommandLine flags: -XX:G1NewSizePercent=20 -XX:+HeapDumpOnOutOfMemoryError -XX:InitialHeapSize=3221225472 -XX:MaxGCPauseMillis=500 -XX:MaxHeapSize=5872025600 -XX:-OmitStackTraceInFastThrow -XX:+PrintGC -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UnlockExperimentalVMOptions -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC

    ## Young GC(以下同,略去详细内容)
    2021-01-08T04:12:09.331+0800: 1172604.919: [GC pause (G1 Evacuation Pause) (young), 0.0184242 secs]
      [Parallel Time: 15.1 ms, GC Workers: 4]
          [GC Worker Start (ms): Min: 1172604919.7, Avg: 1172604919.8, Max: 1172604919.8, Diff: 0.1]
          [Ext Root Scanning (ms): Min: 1.4, Avg: 1.7, Max: 2.6, Diff: 1.2, Sum: 6.9]
          [Update RS (ms): Min: 6.8, Avg: 7.4, Max: 7.8, Diff: 1.0, Sum: 29.8]
            [Processed Buffers: Min: 11, Avg: 18.2, Max: 27, Diff: 16, Sum: 73]
          [Scan RS (ms): Min: 0.4, Avg: 0.6, Max: 0.6, Diff: 0.2, Sum: 2.2]
          [Code Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.3]
          [Object Copy (ms): Min: 4.9, Avg: 5.0, Max: 5.1, Diff: 0.2, Sum: 19.9]
          [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
            [Termination Attempts: Min: 1, Avg: 1.0, Max: 1, Diff: 0, Sum: 4]
          [GC Worker Other (ms): Min: 0.1, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.4]
          [GC Worker Total (ms): Min: 14.8, Avg: 14.9, Max: 15.0, Diff: 0.2, Sum: 59.5]
          [GC Worker End (ms): Min: 1172604934.6, Avg: 1172604934.6, Max: 1172604934.7, Diff: 0.1]
      [Code Root Fixup: 0.0 ms]
      [Code Root Purge: 0.0 ms]
      [Clear CT: 0.5 ms]
      [Other: 2.8 ms]
          [Choose CSet: 0.0 ms]
          [Ref Proc: 0.3 ms]
          [Ref Enq: 0.0 ms]
          [Redirty Cards: 0.1 ms]
          [Humongous Register: 0.2 ms]
          [Humongous Reclaim: 0.0 ms]
          [Free CSet: 1.9 ms]
      [Eden: 2498.0M(2498.0M)->0.0B(2496.0M) Survivors: 6144.0K->6144.0K Heap: 5011.5M(5576.0M)->2513.8M(5576.0M)]
    [Times: user=0.06 sys=0.00, real=0.02 secs] 
    ## 初始标记 initial-mark
    2021-01-08T04:12:18.958+0800: 1172614.546: [GC pause (G1 Evacuation Pause) (young) (initial-mark), 0.0199455 secs]
      ### ......
      [Eden: 2496.0M(2496.0M)->0.0B(2492.0M) Survivors: 6144.0K->8192.0K Heap: 5009.8M(5576.0M)->2515.0M(5576.0M)]
    [Times: user=0.05 sys=0.02, real=0.02 secs] 
    ## 并发根节点扫描
    2021-01-08T04:12:18.979+0800: 1172614.567: [GC concurrent-root-region-scan-start]
    2021-01-08T04:12:19.004+0800: 1172614.592: [GC concurrent-root-region-scan-end, 0.0256504 secs]
    ## 并发标记
    2021-01-08T04:12:19.004+0800: 1172614.592: [GC concurrent-mark-start]
    2021-01-08T04:12:19.214+0800: 1172614.802: [GC concurrent-mark-end, 0.2101424 secs]
    ## 重新标记
    2021-01-08T04:12:19.215+0800: 1172614.803: [GC remark 2021-01-08T04:12:19.215+0800: 1172614.803: [Finalize Marking, 0.0003026 secs] 2021-01-08T04:12:19.215+0800: 1172614.803: [GC ref-proc, 0.7285039 secs] 2021-01-08T04:12:19.944+0800: 1172615.532: [Unloading, 0.0301928 secs], 0.7619789 secs]
    [Times: user=0.95 sys=0.02, real=0.77 secs] 
    ## 清理阶段
    2021-01-08T04:12:19.978+0800: 1172615.566: [GC cleanup 2575M->2567M(5576M), 0.0076275 secs]
    [Times: user=0.00 sys=0.00, real=0.01 secs] 
    2021-01-08T04:12:19.986+0800: 1172615.574: [GC concurrent-cleanup-start]
    2021-01-08T04:12:19.986+0800: 1172615.574: [GC concurrent-cleanup-end, 0.0000396 secs]
    ## 空间收集阶段的 young gc
    2021-01-08T04:12:28.168+0800: 1172623.756: [GC pause (G1 Evacuation Pause) (young), 0.0249811 secs]
       ### ......
      [Eden: 2492.0M(2492.0M)->0.0B(1110.0M) Survivors: 8192.0K->4096.0K Heap: 4999.0M(5576.0M)->2504.2M(5576.0M)]
    [Times: user=0.06 sys=0.03, real=0.02 secs] 
    ## 空间收集阶段的 young gc(mixed)
    2021-01-08T04:12:31.149+0800: 1172626.737: [GC pause (G1 Evacuation Pause) (mixed), 0.0437074 secs]
      ### ......
      [Eden: 1110.0M(1110.0M)->0.0B(1108.0M) Survivors: 4096.0K->6144.0K Heap: 3614.2M(5576.0M)->2206.5M(5576.0M)]
    [Times: user=0.10 sys=0.04, real=0.04 secs] 
    ## 空间收集阶段的 young gc(mixed)
    2021-01-08T04:12:34.734+0800: 1172630.322: [GC pause (G1 Evacuation Pause) (mixed), 0.0397893 secs]
      ### ......
      [Eden: 1108.0M(1108.0M)->0.0B(1108.0M) Survivors: 6144.0K->6144.0K Heap: 3314.5M(5576.0M)->1916.7M(5576.0M)]
    [Times: user=0.10 sys=0.04, real=0.04 secs] 
    ## 空间收集阶段的 young gc(mixed)
    2021-01-08T04:12:39.836+0800: 1172635.424: [GC pause (G1 Evacuation Pause) (mixed), 0.0539989 secs]
      ### ......
      [Eden: 1108.0M(1108.0M)->0.0B(1110.0M) Survivors: 6144.0K->4096.0K Heap: 3024.7M(5576.0M)->1536.4M(5576.0M)]
    [Times: user=0.13 sys=0.05, real=0.05 secs] 
    ## 大对象收集
    [GC pause (G1 Humongous Allocation) (young), 0.0022191 secs]
     [Parallel Time: 1.3 ms, GC Workers: 4]
        [GC Worker Start (ms): Min: 909912.8, Avg: 909913.1, Max: 909913.9, Diff: 1.1]
        [Ext Root Scanning (ms): Min: 0.0, Avg: 0.3, Max: 0.4, Diff: 0.4, Sum: 1.1]
        [Update RS (ms): Min: 0.0, Avg: 0.1, Max: 0.3, Diff: 0.3, Sum: 0.4]
           [Processed Buffers: Min: 0, Avg: 2.2, Max: 3, Diff: 3, Sum: 9]
        [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.1, Diff: 0.1, Sum: 0.1]
        [Termination (ms): Min: 0.0, Avg: 0.5, Max: 0.7, Diff: 0.7, Sum: 1.8]
           [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: 0.0, Avg: 0.9, Max: 1.2, Diff: 1.2, Sum: 3.5]
        [GC Worker End (ms): Min: 909914.0, Avg: 909914.0, Max: 909914.1, Diff: 0.1]
     [Code Root Fixup: 0.0 ms]
     [Code Root Purge: 0.0 ms]
     [Clear CT: 0.0 ms]
     [Other: 0.9 ms]
        [Choose CSet: 0.0 ms]
        [Ref Proc: 0.8 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(2048.0K)->0.0B(2048.0K) Survivors: 0.0B->0.0B Heap: 38.1M(50.0M)->38.1M(50.0M)]
    [Times: user=0.00 sys=0.01, real=0.00 secs] 
    ## Full GC
    [Full GC (Allocation Failure)  38M->37M(50M), 0.0419625 secs]
      [Eden: 0.0B(2048.0K)->0.0B(2048.0K) Survivors: 0.0B->0.0B Heap: 38.1M(50.0M)->37.9M(50.0M)], [Metaspace: 30407K->30407K(1077248K)]
    [Times: user=0.05 sys=0.00, real=0.04 secs] 
    [Full GC (Allocation Failure)  37M->37M(50M), 0.0346627 secs]
      [Eden: 0.0B(2048.0K)->0.0B(2048.0K) Survivors: 0.0B->0.0B Heap: 37.9M(50.0M)->37.9M(50.0M)], [Metaspace: 30407K->30407K(1077248K)]
    [Times: user=0.05 sys=0.00, real=0.04 secs] 
    

低延迟垃圾收集器

  • Shenandoah 收集器
  • ZGC 收集器

常用垃圾收集器公共参数

  • 以下两个命令结合起来可以大致推敲 JVM 默认参数:

      java -XX:+PrintFlagsInitial ${pid}
    
      jinfo ${pid}
  • 以下列举常用的一些公共参数:

    |参数|参数含义|默认值|
    |–|–|–|–|
    |-Xms -Xmx -Xmn|指定堆启动内存、堆最大内存、年轻代内存。比如 -Xmx5g 表示堆最大内存为5g。||
    |-XX:ErrorFile=file|指定 Fatal Error日志文件位置,比如:./java_error_%p.log||
    |-XX:+HeapDumpOnOutOfMemoryError|指示 JVM 发生 OutOfMemory 的时候输出 dump 文件||
    |-XX:-OmitStackTraceInFastThrow|该参数禁用 OmitStackTraceInFastThrow。OmitStackTraceInFastThrow 默认开启,指示 hotspot 使用fast throw来优化这个抛出异常的地方,直接抛出一个事先分配好的、类型匹配的对象,这个对象的message和stack trace都被清空。所以开启OmitStackTraceInFastThrow不利于排查问题。||
    |-XX:+PrintGC|指示输出简要GC日志||
    |-XX:+PrintGCDetails|指示输出详细GC日志||
    |-XX:+PrintGCApplicationStoppedTime |指示打印STW时间||
    |-XX:+PrintGCDateStamps|指示输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)||
    |-XX:+PrintGCTimeStamps |该参数指示输出GC的时间戳(以JVM启动到当期的总时长的时间戳形式)||
    |-XX:+UseCompressedClassPointers |该参数指示压缩kclass指针大小||
    |-XX:+UseCompressedOops|该参数指示进行指针压缩(包含kclass指针和对象指针)||
    |-Xloggc:${GC_LOG_PATH}|该参数指示输出GC日志到文件||
    |-XX:SurvivorRatio=8 |该参数设置的是Eden区与每一个Survivor区的比值,可以反推出占新生代的比值,Eden为8, 两个Survivor为1, Eden占新生代的4/5, 每个Survivor占1/10,两个占1/5|默认8|
    |-XX:MetaspaceSize=64m
    -XX:MaxMetaspaceSize=128M |该参数指定元数据空间初始扩容阈值为64m,最大扩容空间为128M|默认值无穷大|


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK