接下来将深入了解学习JVM,以简单有效的方式整理相关知识,如有本人有错误见解之处,敬请留言告知!谢谢~~
注:IDEA如何配置打印GC日志,大家可以Google、百度一下。

一. 参数分类

根据JVM参数开头可以区分参数类型,共三类:“-”、“-X”、“-XX”,

标准参数(-):所有的JVM实现都必须实现这些参数的功能,而且向后兼容;

例子:-verbose:class,-verbose:gc,-verbose:jni……

非标准参数(-X):默认jvm实现这些参数的功能,但是并不保证所有jvm实现都满足,且不保证向后兼容;

例子:Xms20m,-Xmx20m,-Xmn20m,-Xss128k……

非Stable参数(-XX):此类参数各个jvm实现会有所不同,将来可能会随时取消,需要慎重使用;

例子:-XX:+PrintGCDetails,-XX:-UseParallelGC,-XX:+PrintGCTimeStamps……

二. 参数详解

-XX:+

-XX:-

-XX:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
-Xms                                # Java堆的初始大小
-Xmx # Java堆的最大值
-Xss # 栈容量大小
-Xmn # 新生代的大小
-XX:+PrintGC # 打印GC
-XX:+PrintGCDetails # 打印GC详情
-XX:+PrintGCDateStamps # 打印GC时的时间
-XX:+PrintGCTimeStamps # 打印GC时的时间戳
-XX:+PrintHeapAtGC # 在进行GC的前后打印出堆的信息
-XX:+PrintTenuringDistribution # 打印GC后新生代各个年龄对象的大小
-XX:PretenureSizeThreshold # 设置对象超过指定字节大小时直接分配到老年代
-XX:+HandlePromotionFailure # 是否允许新生代收集担保失败。进行一次minor gc后, 另一块Survivor空间不足时,将直接会在老年代中保留
-XX:MaxTenuringThreshold # 晋升到老年代的对象年龄。每次Minor GC之后,存活年龄就加1,当超过这个值时进入老年代。默认为15
-XX:+PrintGCApplicationStoppedTime # 输出GC造成应用暂停的时间
-XX:+UseSerialGC # 开启Serial收集器
-XX:+UseParNewGC # 开启ParNew收集器
-XX:+UseParallelGC # 开启Parallel Scavenge收集器
-XX:GCTimeRatio # 垃圾收集时间占总时间的比值,相当于吞吐量的倒数,默认99(仅Parallel Scavenge收集器时生效)
-XX:+UseAdaptiveSizePolicy # 动态调整Java堆中各个区域的大小及进入老年代的年龄,默认开启
-XX:+UseParallelOldGC # 开启Parallel Old收集器
-XX:+UseConcMarkSweepGC # 开启CMS收集器
-XX:CMSInitiatingOccupancyFraction # 由于CMS收集存在浮动垃圾,CMS不能等到老年代用尽才进行回收,而是使用率达到设定值就触发垃圾回收
-XX:+UseCMSInitiatingOccupancyOnly # 开启固定老年代使用率的回收阈值,如果不指定,JVM仅在第一次使用设定值,后续则自动调整
-XX:+UseCMSCompactAtFullCollection # 开启对老年代空间进行压缩整理(默认开启)
-XX:CMSFullGCsBeforeCompaction # 设置执行多少次不压缩的Full GC后,紧接着就进行一次压缩整理(默认为0,每次都进行压缩整理)
-XX:+CMSScavengeBeforeRemark # 执行CMS 重新标记(remark)之前进行一次Young GC,这样能有效降低remark时间
-XX:+UseG1GC # 开启G1收集器
-XX:MaxGCPauseMillis # 设置最大GC停顿时间。这是一个软性指标, JVM 会尽量去达成这个指标
-XX:InitiatingHeapOccupancyPercent # 启动并发GC周期时的堆内存占用百分比。G1用它来触发并发GC周期,基于整个堆的使用率而不只是某一代内存的使用比
-XX:ParallelGCThreads # 设置垃圾收集器在并行阶段使用的线程数,默认值随JVM运行的平台不同而不同
-XX:ConcGCThreads # 并发垃圾收集器使用的线程数量。默认值随JVM运行的平台不同而不同
-XX:G1ReservePercent # 设置预留堆大小百分比,防止晋升失败,默认10
-XX:G1HeapRegionSize # 指定每个heap区的大小,默认值将根据 heap size 算出最优解
-XX:InitialSurvivorRatio # 设置Survivor区的比例,默认5
-XX:+PrintAdaptiveSizePolicy # 打印自适应收集的大小。默认关闭
-XX:G1MixedGCCountTarget # 混合GC数量,默认8。减少该值可以解决晋升失败的问题(代价是混合式GC周期的停顿时间会更长)

三. GC日志解析

1. 正常日志

Java8默认的GC收集器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
参数示例:
-Xms20M
-Xmx20M
-Xss128K
-Xmn8M
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps

Heap
PSYoungGen total 7168K, used 2197K [0x00000000ff800000, 0x0000000100000000, 0x0000000100000000)
eden space 6144K, 35% used [0x00000000ff800000,0x00000000ffa25678,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
ParOldGen total 12288K, used 0K [0x00000000fec00000, 0x00000000ff800000, 0x00000000ff800000)
object space 12288K, 0% used [0x00000000fec00000,0x00000000fec00000,0x00000000ff800000)
Metaspace used 3099K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 337K, capacity 388K, committed 512K, reserved 1048576K

PSYoungGen total 7168K, used 2197K

  • PSYoungGen:新生代采用了Parallel Scavenge收集器(PS: Parallel Scavenge)

  • total 7168K:共有7168K

  • used 2197K:已使用2197K

    eden space 6144K, 35% used

    ​ (默认 Eden : from : to = 8 : 1 : 1,可以通过 –XX:SurvivorRatio 调整)

    • 伊甸区,共有6144K,已使用%35

    from space 1024K, 0% used

    • 幸存区S0,共有1024K,已使用%0

    to space 1024K, 0% used

    • 幸存区S1,共有1024K,已使用%0

ParOldGen total 12288K, used 0K

  • ParOldGen:表示老年代采用Parallel Old收集器(Par: Parallel Old)

  • total 12288K:共有12288K

  • used 0K:已使用0K

    object space 12288K, 0% used

    • 老年代,共有12288K,已使用%0

Metaspace used 3099K, capacity 4496K, committed 4864K, reserved 1056768K

  • Metaspace:元空间

  • jdk1.7之前,HotSpot虚拟机对于⽅法区的实现称之为“永久代(Permanent Generation)”

  • jdk1.8之后,HotSpot虚拟机对于⽅法区的实现称之为“元空间(Meta Space)”

2.垃圾回收日志

Java8默认的GC收集器

  • 代码示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* -- 垃圾回收示例 1
* <pre>
* VM参数示例:
* -Xms20M
* -Xmx20M
* -Xss128K
* -Xmn8M
* -XX:+PrintGC
* -XX:+PrintGCDetails
* -XX:+PrintGCDateStamps
* -XX:+PrintGCTimeStamps
* </pre>
*
* @author lmay.Zhou
* @date 2020/11/5 22:08 星期四
* @qq 379839355
* @email lmay@lmaye.com
* @since JDK1.8
*/
public class Gc01 {
/**
* 1MB
*/
private static final int MB = 1024 * 1024;

public static void main(String[] args) {
byte[] b1 = new byte[4 * MB];
byte[] b2 = new byte[4 * MB];
byte[] b3 = new byte[4 * MB];
byte[] b4 = new byte[2 * MB];
}
}
  • GC日志
1
2
3
4
5
6
7
8
9
10
11
12
2020-11-06T21:05:43.932+0800: 0.131: [GC (Allocation Failure) [PSYoungGen: 2229K->936K(7168K)] 10421K->9136K(19456K), 0.0008828 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
2020-11-06T21:05:43.934+0800: 0.133: [GC (Allocation Failure) --[PSYoungGen: 5277K->5277K(7168K)] 13477K->13477K(19456K), 0.0012895 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
2020-11-06T21:05:43.936+0800: 0.134: [Full GC (Ergonomics) [PSYoungGen: 5277K->4844K(7168K)] [ParOldGen: 8200K->8192K(12288K)] 13477K->13036K(19456K), [Metaspace: 3276K->3276K(1056768K)], 0.0046614 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
PSYoungGen total 7168K, used 5090K [0x00000000ff800000, 0x0000000100000000, 0x0000000100000000)
eden space 6144K, 82% used [0x00000000ff800000,0x00000000ffcf8a48,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 12288K, used 10240K [0x00000000fec00000, 0x00000000ff800000, 0x00000000ff800000)
object space 12288K, 83% used [0x00000000fec00000,0x00000000ff6000c8,0x00000000ff800000)
Metaspace used 3312K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 357K, capacity 388K, committed 512K, reserved 1048576K

2020-11-06T21:05:43.932+0800: 0.131: [GC (Allocation Failure) [PSYoungGen: 2229K->936K(7168K)] 10421K->9136K(19456K), 0.0008828 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

  • 2020-11-06T21:05:43.932+0800:GC日志记录时间

  • 0.131:GC发生的时间,Java虚拟机启动以来运行的秒数

  • GC (Allocation Failure):发生了一次垃圾回收。如果有“Full”,说明这次Full GC是发生了Stop-The-World(STW)。没有,则就次就是Minor GC。注意不是用来区分新生代GC还是老年代GC。Allocation Failure的原因是新生代中没有足够的内存能够存放需要分配的数据而失败。

  • PSYoungGen:使用的GC收集器名称(PS: Parallel Scavenge)。

  • 2229K->936K(7168K):GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)

  • 10421K->9136K(19456K):GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)

  • 0.0008828 secs:该内存区域GC所占用的时间,单位是秒

  • [Times: user=0.00 sys=0.00, real=0.00 secs]:分别表示用户态消耗的CPU时间、内核态消耗的CPU时间和总耗时

2020-11-06T21:05:43.936+0800: 0.134: [Full GC (Ergonomics) [PSYoungGen: 5277K->4844K(7168K)] [ParOldGen: 8200K->8192K(12288K)] 13477K->13036K(19456K), [Metaspace: 3276K->3276K(1056768K)], 0.0046614 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

  • 2020-11-06T21:05:43.936+0800:GC日志记录时间
  • 0.134:GC发生的时间,Java虚拟机启动以来运行的秒数
  • Full GC (Ergonomics):发生了一次Full GC(Ergonomics),且是一次全局GC
  • [PSYoungGen: 5277K->4844K(7168K)]:新生代进行了一次GC。[GC收集器名称:GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)]
  • [ParOldGen: 8200K->8192K(12288K)] :老年代进行了一次GC。[GC收集器名称:GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)]
  • 13477K->13036K(19456K):GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)
  • [Metaspace: 3276K->3276K(1056768K)]:元空间(方法区)进行了一次GC。但是GC前后内存使用情况并没有发生任何变化,且元空间总容量为1G
  • 0.0046614 secs:该内存区域GC所占用的时间,单位是秒
  • [Times: user=0.00 sys=0.00, real=0.00 secs]:分别表示用户态消耗的CPU时间、内核态消耗的CPU时间和总耗时
3.Serial 收集器日志
  • 代码示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* -- Serial 收集器
* : 单线程的收集器,收集垃圾时,必须Stop The World,使用复制算法。
*
* <pre>
* VM参数示例: Serial + Serial Old
* -Xms20M
* -Xmx20M
* -Xss128K
* -Xmn8M
* -XX:+PrintGC
* -XX:+PrintGCDetails
* -XX:+UseSerialGC
* </pre>
*
* @author lmay.Zhou
* @date 2020/11/5 22:08 星期四
* @qq 379839355
* @email lmay@lmaye.com
* @since JDK1.8
*/
public class SerialGc {
private static final int MB = 1024 * 1024;

public static void main(String[] args) {
byte[] b1 = new byte[4 * MB];
byte[] b2 = new byte[4 * MB];
byte[] b3 = new byte[4 * MB];
byte[] b4 = new byte[6 * MB];
}
}
  • GC日志
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[GC (Allocation Failure) [DefNew: 6178K->744K(7424K), 0.0028888 secs] 6178K->4840K(19712K), 0.0029277 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [DefNew: 5039K->1K(7424K), 0.0027075 secs] 9135K->8933K(19712K), 0.0027308 secs] [Times: user=0.00 sys=0.02, real=0.00 secs]
[GC (Allocation Failure) [DefNew: 4141K->4141K(7424K), 0.0000139 secs][Tenured: 8932K->8932K(12288K), 0.0019722 secs] 13073K->13029K(19712K), [Metaspace: 3152K->3152K(1056768K)], 0.0020200 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [Tenured: 8932K->8903K(12288K), 0.0015452 secs] 13029K->13000K(19712K), [Metaspace: 3152K->3152K(1056768K)], 0.0015649 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
def new generation total 7424K, used 4422K [0x00000000fec00000, 0x00000000ff400000, 0x00000000ff400000)
eden space 6656K, 66% used [0x00000000fec00000, 0x00000000ff051b80, 0x00000000ff280000)
from space 768K, 0% used [0x00000000ff280000, 0x00000000ff280000, 0x00000000ff340000)
to space 768K, 0% used [0x00000000ff340000, 0x00000000ff340000, 0x00000000ff400000)
tenured generation total 12288K, used 8903K [0x00000000ff400000, 0x0000000100000000, 0x0000000100000000)
the space 12288K, 72% used [0x00000000ff400000, 0x00000000ffcb1e48, 0x00000000ffcb2000, 0x0000000100000000)
Metaspace used 3238K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 352K, capacity 388K, committed 512K, reserved 1048576K
## 内存泄漏异常 OutOfMemoryError
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.lmay.jvm.structure.gc.SerialGc.main(SerialGc.java:32)

[GC (Allocation Failure) [DefNew: 6178K->744K(7424K), 0.0028888 secs] 6178K->4840K(19712K), 0.0029277 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

  • GC (Allocation Failure):发生了一次垃圾回收

  • DefNew:Serial收集器中的新生代名称为“Default New Generation”

  • 6178K->744K(7424K):GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)

  • 0.0028888 secs:该内存区域GC所占用的时间,单位是秒

  • 6178K->4840K(19712K):GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)

  • [Times: user=0.00 sys=0.02, real=0.00 secs] :分别表示用户态消耗的CPU时间、内核态消耗的CPU时间和总耗时

[Full GC (Allocation Failure) [Tenured: 8932K->8903K(12288K), 0.0015452 secs] 13029K->13000K(19712K), [Metaspace: 3152K->3152K(1056768K)], 0.0015649 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

  • Full GC (Allocation Failure):发生了一次Full GC
  • [Tenured: 8932K->8903K(12288K), 0.0015452 secs]:老年代进行了一次GC。[GC收集器名称:GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量),GC耗时]
  • 13029K->13000K(19712K):GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)
  • [Metaspace: 3152K->3152K(1056768K)]:元空间(方法区)进行了一次GC。但是GC前后内存使用情况并没有发生任何变化,且元空间总容量为1G
  • [Times: user=0.00 sys=0.00, real=0.00 secs]:分别表示用户态消耗的CPU时间、内核态消耗的CPU时间和总耗时
4.ParNew 收集器日志
  • 代码示例(ParNew + Serial Old)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* -- ParNew 收集器
* : Serial收集器的多线程版本,也需要Stop The World,复制算法。
*
* <pre>
* VM参数示例: ParNew + Serial Old
* -Xms20M
* -Xmx20M
* -Xss128K
* -Xmn8M
* -XX:+PrintGC
* -XX:+PrintGCDetails
* -XX:+UseParNewGC
* </pre>
*
* @author lmay.Zhou
* @date 2020/11/6 22:47 星期五
* @qq 379839355
* @email lmay@lmaye.com
* @since JDK1.8
*/
public class ParNewGc {
private static final int MB = 1024 * 1024;

public static void main(String[] args) {
byte[] b1 = new byte[4 * MB];
byte[] b2 = new byte[4 * MB];
byte[] b3 = new byte[4 * MB];
byte[] b4 = new byte[2 * MB];
}
}
  • GC日志
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[GC (Allocation Failure) [ParNew: 6178K->768K(7424K), 0.0026432 secs] 6178K->4882K(19712K), 0.0026981 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [ParNew: 5063K->153K(7424K), 0.0025039 secs] 9177K->9135K(19712K), 0.0025227 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [ParNew: 4294K->4294K(7424K), 0.0000139 secs][Tenured: 8981K->8981K(12288K), 0.0020052 secs] 13275K->13078K(19712K), [Metaspace: 3152K->3152K(1056768K)], 0.0020487 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
[Full GC (Allocation Failure) [Tenured: 8981K->8904K(12288K), 0.0021765 secs] 13078K->13001K(19712K), [Metaspace: 3152K->3152K(1056768K)], 0.0021933 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
par new generation total 7424K, used 4356K [0x00000000fec00000, 0x00000000ff400000, 0x00000000ff400000)
eden space 6656K, 65% used [0x00000000fec00000, 0x00000000ff041158, 0x00000000ff280000)
from space 768K, 0% used [0x00000000ff280000, 0x00000000ff280000, 0x00000000ff340000)
to space 768K, 0% used [0x00000000ff340000, 0x00000000ff340000, 0x00000000ff400000)
tenured generation total 12288K, used 8904K [0x00000000ff400000, 0x0000000100000000, 0x0000000100000000)
the space 12288K, 72% used [0x00000000ff400000, 0x00000000ffcb2168, 0x00000000ffcb2200, 0x0000000100000000)
Metaspace used 3243K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 353K, capacity 388K, committed 512K, reserved 1048576K
## 内存泄漏异常 OutOfMemoryError
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.lmay.jvm.structure.gc.ParNewGc.main(ParNewGc.java:46)
## HotSpot JVM 警告:不建议将ParNew年轻收集器与Serial Old收集器一起使用,并且在将来的发行版中可能会删除它。
Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release

[GC (Allocation Failure) [ParNew: 6178K->768K(7424K), 0.0026432 secs] 6178K->4882K(19712K), 0.0026981 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

  • GC (Allocation Failure):发生了一次垃圾回收

  • ParNew:ParNew收集器中的新生代名称为“Parallel New Generation”

  • 6178K->768K(7424K):GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)

  • 0.0026432 secs:该内存区域GC所占用的时间,单位是秒

  • 6178K->4882K(19712K):GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)

  • [Times: user=0.00 sys=0.00, real=0.00 secs] :分别表示用户态消耗的CPU时间、内核态消耗的CPU时间和总耗时

※ 其他的就不解释了,如上示例分析即可

5.Parallel Scavenge 收集器
  • 代码示例(Parallel Scavenge + Parallel Old)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* -- Parallel Scavenge 收集器
* : 新生代收集器,复制算法的收集器,并发的多线程收集器,目标是达到一个可控的吞吐量。如果虚拟机总共运行100分钟,其中垃圾花掉1分钟,吞吐量就是99%。
*
* <pre>
* Parallel Old 收集器: 是ParallelScavenge收集器的老年代版本,使用多线程,标记-整理算法。
* VM参数示例: Parallel Scavenge + Parallel Old
* -Xms20M
* -Xmx20M
* -Xss128K
* -Xmn8M
* -XX:+PrintGC
* -XX:+PrintGCDetails
* -XX:+UseParallelGC
* </pre>
*
* @author lmay.Zhou
* @date 2020/11/7 11:48 星期六
* @qq 379839355
* @email lmay@lmaye.com
* @since JDK1.8
*/
public class ParallelScavengeGc {
private static final int MB = 1024 * 1024;

public static void main(String[] args) {
byte[] b1 = new byte[4 * MB];
byte[] b2 = new byte[4 * MB];
byte[] b3 = new byte[4 * MB];
byte[] b4 = new byte[6 * MB];
}
}
  • GC日志
1
2
3
4
5
6
7
8
9
10
11
12
[GC (Allocation Failure) [PSYoungGen: 2228K->936K(7168K)] 10420K->9136K(19456K), 0.0015886 secs] [Times: user=0.05 sys=0.03, real=0.00 secs] 
[GC (Allocation Failure) --[PSYoungGen: 5277K->5277K(7168K)] 13477K->13477K(19456K), 0.0009846 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (Ergonomics) [PSYoungGen: 5277K->4846K(7168K)] [ParOldGen: 8200K->8192K(12288K)] 13477K->13038K(19456K), [Metaspace: 3300K->3300K(1056768K)], 0.0049473 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
Heap
PSYoungGen total 7168K, used 5093K [0x00000000ff800000, 0x0000000100000000, 0x0000000100000000)
eden space 6144K, 82% used [0x00000000ff800000,0x00000000ffcf9608,0x00000000ffe00000)
from space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 12288K, used 10240K [0x00000000fec00000, 0x00000000ff800000, 0x00000000ff800000)
object space 12288K, 83% used [0x00000000fec00000,0x00000000ff6000c8,0x00000000ff800000)
Metaspace used 3329K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 359K, capacity 388K, committed 512K, reserved 1048576K

※ 其他的就不解释了,如上示例分析即可

**[Full GC (Ergonomics) [PSYoungGen: 5277K->4846K(7168K)] [ParOldGen: 8200K->8192K(12288K)] 13477K->13038K(19456K), [Metaspace: 3300K->3300K(1056768K)], 0.0049473 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] **

  • Full GC (Ergonomics) :发生了一次Full GC(Ergonomics)
  • [PSYoungGen: 5277K->4846K(7168K)]:新生代: GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)
  • [ParOldGen: 8200K->8192K(12288K)]:老年代:GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)
  • 13477K->13038K(19456K):GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)
  • [Metaspace: 3300K->3300K(1056768K)]:元空间: GC前后内存使用情况并没有发生任何变化,且元空间总容量为1G
  • 0.0049473 secs:该内存区域GC所占用的时间,单位是秒
  • [Times: user=0.00 sys=0.00, real=0.01 secs]:分别表示用户态消耗的CPU时间、内核态消耗的CPU时间和总耗时
6.CMS 收集器日志
  • GC日志(ParNew + CMS)

    新生代:采用 stop-the-world mark-copy 算法;

    年老代:采用 Mostly Concurrent mark-sweep 算法;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
参数示例:
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC

[GC (Allocation Failure) [ParNew: 613404K->68068K(613440K), 0.1020465 secs] 10885349K->10880154K(12514816K), 0.1021309 secs] [Times: user=0.78 sys=0.01, real=0.11 secs]
[GC (CMS Initial Mark) [1 CMS-initial-mark: 10812086K(11901376K)] 10887844K(12514816K), 0.0001997 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[CMS-concurrent-mark-start]
[CMS-concurrent-mark: 0.035/0.035 secs] [Times: user=0.07 sys=0.00, real=0.03 secs]
[CMS-concurrent-preclean-start]
[CMS-concurrent-preclean: 0.016/0.016 secs] [Times: user=0.02 sys=0.00, real=0.02 secs]
[CMS-concurrent-abortable-preclean-start]
[CMS-concurrent-abortable-preclean: 0.167/1.074 secs] [Times: user=0.20 sys=0.00, real=1.07 secs]
[GC (CMS Final Remark) [YG occupancy: 387920 K (613440 K)]65.550: [Rescan (parallel) , 0.0085125 secs]65.559: [weak refs processing, 0.0000243 secs]65.559: [class unloading, 0.0013120 secs]65.560: [scrub symbol table, 0.0008345 secs]65.561: [scrub string table, 0.0001759 secs][1 CMS-remark: 10812086K(11901376K)] 11200006K(12514816K), 0.0110730 secs] [Times: user=0.06 sys=0.00, real=0.01 secs]
[CMS-concurrent-sweep-start]
[CMS-concurrent-sweep: 0.027/0.027 secs] [Times: user=0.03 sys=0.00, real=0.03 secs]
[CMS-concurrent-reset-start]
[CMS-concurrent-reset: 0.012/0.012 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]

[GC (Allocation Failure) [ParNew: 613404K->68068K(613440K), 0.1020465 secs] 10885349K->10880154K(12514816K), 0.1021309 secs] [Times: user=0.78 sys=0.01, real=0.11 secs]

  • GC (Allocation Failure):发生了一次垃圾回收

  • ParNew:ParNew收集器中的新生代名称为“Parallel New Generation”

  • 613404K->68068K(613440K):GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)

  • 0.1020465 secs:该内存区域GC所占用的时间,单位是秒

  • 10885349K->10880154K(12514816K):GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)

  • [Times: user=0.78 sys=0.01, real=0.11 secs]:分别表示用户态消耗的CPU时间、内核态消耗的CPU时间和总耗时

[GC (CMS Initial Mark) [1 CMS-initial-mark: 10812086K(11901376K)] 10887844K(12514816K), 0.0001997 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

  • GC (CMS Initial Mark):发生了一次STW垃圾回收(CMS 初始标记)
  • CMS-initial-mark:1> CMS 初始化标记
  • 10812086K(11901376K):当前老年代已使用容量(老年代总容量)
  • 10887844K(12514816K):当前Java堆已使用过容量(Java堆总容量)
  • [Times: user=0.00 sys=0.00, real=0.00 secs]:分别表示用户态消耗的CPU时间、内核态消耗的CPU时间和总耗时

[CMS-concurrent-mark-start]

  • [CMS-concurrent-mark-start]:CMS 启动并发标记

[CMS-concurrent-mark: 0.035/0.035 secs]

  • CMS-concurrent-mark:2> CMS 并发标记
  • 0.035/0.035 secs:该阶段持续的时间和时钟时间

[CMS-concurrent-preclean-start]

  • [CMS-concurrent-preclean-start]:CMS 启动并发预清理

[CMS-concurrent-preclean: 0.016/0.016 secs]

  • CMS-concurrent-preclean:**3> **CMS 并发预清理
  • 0.016/0.016 secs:该阶段持续的时间和时钟时间

[CMS-concurrent-abortable-preclean-start]

  • [CMS-concurrent-abortable-preclean-start]:CMS 启动并发可终止预清理

[CMS-concurrent-abortable-preclean: 0.167/1.074 secs]

  • CMS-concurrent-abortable-preclean:4> CMS 并发可终止预清理
  • 0.167/1.074 secs:该阶段持续的时间和时钟时间

[GC (CMS Final Remark) [YG occupancy: 387920 K (613440 K)]65.550: [Rescan (parallel) , 0.0085125 secs]65.559: [weak refs processing, 0.0000243 secs]65.559: [class unloading, 0.0013120 secs]65.560: [scrub symbol table, 0.0008345 secs]65.561: [scrub string table, 0.0001759 secs][1 CMS-remark: 10812086K(11901376K)] 11200006K(12514816K), 0.0110730 secs]

  • GC (CMS Final Remark) :发生了一次STW垃圾回收(**5>**CMS 最终标记)
  • [YG occupancy: 387920 K (613440 K)]:新生代当前已使用容量(总容量)
  • [Rescan (parallel) , 0.0085125 secs]:这个阶段在应用停止的阶段完成存活对象的标记工作
  • [weak refs processing, 0.0000243 secs]:第一个子阶段,进行弱引用处理
  • [class unloading, 0.0013120 secs]:第二个子阶段,卸载未使用的类
  • [scrub symbol table, 0.0008345 secs]:最后一个子阶段,清理分别保存类级元数据和内部化字符串的符号表和字符串表
  • 10812086K(11901376K):在这个阶段之后老年代占有的内存大小和老年代的容量
  • 11200006K(12514816K):在这个阶段之后整个堆的内存大小和整个堆的容量

[CMS-concurrent-sweep-start]

  • [CMS-concurrent-sweep-start]:CMS 启动并发清除

[CMS-concurrent-sweep: 0.027/0.027 secs]

  • CMS-concurrent-sweep:6> CMS 并发清除
  • 0.027/0.027 secs:该阶段持续的时间和时钟时间

[CMS-concurrent-reset-start]

  • [CMS-concurrent-reset-start]:CMS 启动并发重置

[CMS-concurrent-reset: 0.012/0.012 secs]

  • CMS-concurrent-reset:7> CMS 并发重置
  • 0.012/0.012 secs:该阶段持续的时间和时钟时间
7.G1 收集器
  • 代码示例 G1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* -- G1 收集器
* : 标记整理算法实现,运作流程主要包括以下:初始标记,并发标记,最终标记,筛选标记。不会产生空间碎片,可以精确地控制停顿。
*
* <pre>
* VM参数示例: G1
* -Xms20M
* -Xmx20M
* -Xss128K
* -Xmn8M
* -XX:+PrintGC
* -XX:+PrintGCDetails
* -XX:+PrintGCDateStamps
* -XX:+UseG1GC
* </pre>
*
* @author lmay.Zhou
* @date 2020/11/7 11:50 星期六
* @qq 379839355
* @email lmay@lmaye.com
* @since JDK1.8
*/
public class G1Gc {
private static final int MB = 1024 * 1024;

public static void main(String[] args) {
byte[] b1 = new byte[4 * MB];
byte[] b2 = new byte[4 * MB];
byte[] b3 = new byte[4 * MB];
byte[] b4 = new byte[2 * MB];
}
}
  • GC日志
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
2020-11-08T00:20:23.316+0800: [GC pause (G1 Humongous Allocation) (young) (initial-mark), 0.0011210 secs]
[Parallel Time: 0.8 ms, GC Workers: 8]
[GC Worker Start (ms): Min: 118.6, Avg: 118.8, Max: 119.4, Diff: 0.7]
[Ext Root Scanning (ms): Min: 0.0, Avg: 0.2, Max: 0.7, Diff: 0.7, Sum: 1.9]
[Code Root Marking (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[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.0, Avg: 0.3, Max: 0.5, Diff: 0.5, Sum: 2.5]
[Termination (ms): Min: 0.0, Avg: 0.1, Max: 0.1, Diff: 0.1, Sum: 0.6]
[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.6, Max: 0.8, Diff: 0.7, Sum: 5.2]
[GC Worker End (ms): Min: 119.4, Avg: 119.4, Max: 119.4, Diff: 0.0]
[Code Root Fixup: 0.0 ms]
[Code Root Migration: 0.0 ms]
[Code Root Purge: 0.0 ms]
[Clear CT: 0.1 ms]
[Other: 0.2 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 0.1 ms]
[Ref Enq: 0.0 ms]
[Redirty Cards: 0.0 ms]
[Free CSet: 0.0 ms]
[Eden: 2048.0K(8192.0K)->0.0B(7168.0K) Survivors: 0.0B->1024.0K Heap: 6144.0K(20.0M)->5040.1K(20.0M)]
[Times: user=0.06 sys=0.03, real=0.00 secs]
2020-11-08T00:20:23.318+0800: [GC concurrent-root-region-scan-start]
2020-11-08T00:20:23.319+0800: [GC concurrent-root-region-scan-end, 0.0007939 secs]
2020-11-08T00:20:23.319+0800: [GC concurrent-mark-start]
2020-11-08T00:20:23.319+0800: [GC concurrent-mark-end, 0.0000427 secs]
2020-11-08T00:20:23.319+0800: [GC remark [GC ref-proc, 0.0001080 secs], 0.0006035 secs]
[Times: user=0.00 sys=0.00, real=0.00 secs]
2020-11-08T00:20:23.322+0800: [GC cleanup 13M->13M(20M), 0.0005493 secs]
[Times: user=0.00 sys=0.00, real=0.00 secs]
2020-11-08T00:20:23.322+0800: [GC pause (G1 Humongous Allocation) (young), 0.0009365 secs]
[Parallel Time: 0.7 ms, GC Workers: 8]
[GC Worker Start (ms): Min: 124.7, Avg: 124.8, Max: 125.3, Diff: 0.6]
[Ext Root Scanning (ms): Min: 0.0, Avg: 0.1, Max: 0.2, Diff: 0.2, Sum: 0.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.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.4, Max: 0.5, Diff: 0.5, Sum: 3.1]
[Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.3]
[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.5, Max: 0.6, Diff: 0.6, Sum: 4.1]
[GC Worker End (ms): Min: 125.3, Avg: 125.3, Max: 125.3, Diff: 0.0]
[Code Root Fixup: 0.0 ms]
[Code Root Migration: 0.0 ms]
[Code Root Purge: 0.0 ms]
[Clear CT: 0.1 ms]
[Other: 0.1 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 0.1 ms]
[Ref Enq: 0.0 ms]
[Redirty Cards: 0.0 ms]
[Free CSet: 0.0 ms]
[Eden: 1024.0K(7168.0K)->0.0B(7168.0K) Survivors: 1024.0K->1024.0K Heap: 13.2M(20.0M)->13.2M(20.0M)]
[Times: user=0.00 sys=0.00, real=0.00 secs]
2020-11-08T00:20:23.324+0800: [Full GC (Allocation Failure) 13M->12M(20M), 0.0021667 secs]
[Eden: 0.0B(7168.0K)->0.0B(8192.0K) Survivors: 1024.0K->0.0B Heap: 13.2M(20.0M)->12.7M(20.0M)], [Metaspace: 3186K->3186K(1056768K)]
[Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
garbage-first heap total 20480K, used 15079K [0x00000000fec00000, 0x0000000100000000, 0x0000000100000000)
region size 1024K, 1 young (1024K), 0 survivors (0K)
Metaspace used 3340K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 360K, capacity 388K, committed 512K, reserved 1048576K

最后更新: 2021年04月01日 11:03

原始链接: https://www.lmaye.com/2020/11/06/20201106005801/

× 多少都行~
打赏二维码