文章目录
前言
GC 日志可以提供虚拟机各分代垃圾回收的情况,需要注意的是,不同的垃圾回收器在GC 日志中名字并不相同。
JDK 版本
本文使用 JDK 1.8 x64 进行相关测试
查看垃圾回收器
测试代码
从实践来说,可以通过限制虚拟机内存大小,然后不断创建对象来触发 GC,也可以直接调用 System.gc(),本文采用了后者——更简单,直观。
当然,作为测试,我们还是增加了一些JVM 的配置参数,用于日志能够展示在控制台上
-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728
public class GcTest {
//-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728
private static final int _1MB = 1024 * 1024;
private static final int _4MB = 4*1024 * 1024;
/**
* 小对象先保存到 新生代 Eden
*/
public static void testThreshold(){
byte[] allocation;
allocation = new byte[1 * _1MB];
}
/**
* 大对象直接进入老年代
* -XX:PretenureSizeThreshold=3145728
*/
public static void testPretenureSizeThreshold(){
byte[] allocation;
allocation = new byte[1 * _4MB];
}
public static void main(String[] args) {
//触发老年代GC
for(int j=0;j<3;j++) {
testPretenureSizeThreshold();
}
//触发新生代GC
for(int i=0;i<10;i++) {
GcTest.testThreshold();
}
//手动触发GC
System.gc();
}
}
控制台内容
控制台内容包含了两个部分,第一个部分是 GC 信息,第二个部分是 Heap 信息
其中 GC 信息就是本文要介绍的GC 日志。
Heap 信息属于PrintGCDetails 的附加信息。
[GC (System.gc()) [PSYoungGen: 1740K->729K(9216K)] 1740K->737K(19456K), 0.0016883 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 729K->0K(9216K)] [ParOldGen: 8K->596K(10240K)] 737K->596K(19456K), [Metaspace: 2677K->2677K(1056768K)], 0.0053865 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
Heap
PSYoungGen total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614920,0x00000007bfe00000)
from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
to space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
ParOldGen total 10240K, used 596K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
object space 10240K, 5% used [0x00000007bec00000,0x00000007bec950e8,0x00000007bf600000)
Metaspace used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 288K, capacity 386K, committed 512K, reserved 1048576K
内容解析-GC 信息
[GC (System.gc()) [PSYoungGen: 1740K->729K(9216K)] 1740K->737K(19456K), 0.0016883 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 729K->0K(9216K)] [ParOldGen: 8K->596K(10240K)] 737K->596K(19456K), [Metaspace: 2677K->2677K(1056768K)], 0.0053865 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
GC 日志以是否Stop The World 分为两类
GC 日志可以分为两种,一种是 [GC
开头,一种是 [Full GC
开头,二者的区别在于,[Full GC
表明该垃圾回收过程发生了 Stop The World
,需要强调的是,不要将GC 日志中 Full GC 关键字和 老年代的垃圾回收 Full GC 混淆,在GC 日志中 年轻代和老年代的日志是在一起的。
如果垃圾回收是由 Java 代码
System.gc()
来触发的,则GC 日志中会增加一个(System.gc()),如本文的 [GC (System.gc()) 和 [Full GC (System.gc())
如果垃圾回收是由于内存空间不够,则会显示分配失败 [GC (Allocation Failure)
此外还会有其他类型的情况
[GC````和``[Full GC
中间部分的含义:PsYoungGen 是年轻代的垃圾回收信息
ParOldGen是老年代的垃圾回收信息
Metaspace是元空间的垃圾回收信息
最后一部分 Times 表示垃圾回收期间各部分时间段占用的事件比重
比如 [PSYoungGen: 729K->0K(9216K)]
表示:新生代使用的是 ParallelGC 这种垃圾回收器,新生代总大小为 9216K,垃圾回收前后的内存占用大小为 729K->0K ,即所占用的 729K 空间全部被回收了
不同垃圾回收器日志关键字不同
GC 日志使用不同的关键字来区分不同的垃圾回收期,你应该了解到虚拟机垃圾回收器有多种不同的搭配方式。本文在下面内容中通过不同的VM 配置对不同情况下的GC日志关键字进行归纳总结。
新生代、老年代垃圾回收器的搭配连线图(CMS 是可以和 Serial Old 同时使用的)
内容解析-Heap 信息
Heap
PSYoungGen total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614920,0x00000007bfe00000)
from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
to space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
ParOldGen total 10240K, used 596K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
object space 10240K, 5% used [0x00000007bec00000,0x00000007bec950e8,0x00000007bf600000)
Metaspace used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 288K, capacity 386K, committed 512K, reserved 1048576K
Heap 信息还是很明显的,PSYoungGen 表示年轻代垃圾回收器为 Parallel Scavenge,此外还有年轻代的 eden 、from、to 的信息;ParOldGen 表示老年代垃圾回收器为 Parallel Old,Metaspace 表示元数据信息,
total 表示总大小,used 表示已用
通过 Heap 信息,也可以分辨出来当前所用的是何种垃圾回收器
指定垃圾回收器与GC 关键字
通过参数指定垃圾回收器
参数 | 描述 |
---|---|
-XX:+UseSerialGC | def new generation (Serial) |
-XX:+UseParNewGC | par new generation |
-XX:+UseParallelGC | PSYoungGen |
-XX:+UseParallelOldGC | PSYoungGen |
-XX:+UseConcMarkSweepGC (CMS) | par new generation |
其他参数延伸
参数 | 描述 |
---|---|
SurvivorRatio | |
PretenureSizeThreshold | |
MaxTenuringThreshold | |
UseAdaptiveSizePolicy | |
HandlePromotionFailure | |
ParallelGCThreads | |
GCTimeRatio | |
MaxGCPauseMills | |
CMSInitiatingOccupancyFraction | |
UseCMSCompactAtFullCollection | |
CMSFullGCsBeforeCompaction |
垃圾回收器关键字规律总结
配置 | 年轻代 | 老年代 | 元数据 |
---|---|---|---|
-XX:+UseSerialGC | def new generation | tenured generation | Metaspace |
-XX:+UseParNewGC | par new generation | tenured generation | Metaspace |
-XX:+UseParallelGC | PSYoungGen | ParOldGen | Metaspace |
-XX:+UseParallelOldGC | PSYoungGen | ParOldGen | Metaspace |
-XX:+UseConcMarkSweepGC | par new generation | concurrent mark-sweep generation | Metaspace |
GC 详情展示
-XX:+UseSerialGC
垃圾回收器: Serial+ SerialOld
GC 日志
[GC (Allocation Failure) [Tenured: 8192K->596K(10240K), 0.0034819 secs] 9932K->596K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0035603 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [DefNew: 7331K->0K(9216K), 0.0003829 secs] 12024K->4692K(19456K), 0.0004152 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [Tenured: 4692K->596K(10240K), 0.0031400 secs] 7928K->596K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0031873 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
堆信息
Heap
def new generation total 9216K, used 82K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
eden space 8192K, 1% used [0x00000007bec00000, 0x00000007bec14920, 0x00000007bf400000)
from space 1024K, 0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)
to space 1024K, 0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000)
tenured generation total 10240K, used 596K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
the space 10240K, 5% used [0x00000007bf600000, 0x00000007bf6950e8, 0x00000007bf695200, 0x00000007c0000000)
Metaspace used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 288K, capacity 386K, committed 512K, reserved 1048576K
-XX:+UseParNewGC
垃圾回收器: PawNew+64位时 SerialOld
GC 日志
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) [Tenured: 8192K->596K(10240K), 0.0045567 secs] 9932K->596K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0046114 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[GC (Allocation Failure) [ParNew: 7331K->0K(9216K), 0.0005674 secs] 12024K->4692K(19456K), 0.0006037 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [Tenured: 4692K->596K(10240K), 0.0024158 secs] 7928K->596K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0024644 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
堆信息
Heap
par new generation total 9216K, used 82K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
eden space 8192K, 1% used [0x00000007bec00000, 0x00000007bec14920, 0x00000007bf400000)
from space 1024K, 0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)
to space 1024K, 0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000)
tenured generation total 10240K, used 596K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
the space 10240K, 5% used [0x00000007bf600000, 0x00000007bf6950e8, 0x00000007bf695200, 0x00000007c0000000)
Metaspace used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 288K, capacity 386K, committed 512K, reserved 1048576K
-XX:+UseParallelGC
垃圾回收器: Parallel Scavenge+Parallel Old
GC 日志
[GC (Allocation Failure) [PSYoungGen: 7884K->745K(9216K)] 16076K->8946K(19456K), 0.0018850 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 8077K->681K(9216K)] 16277K->8882K(19456K), 0.0015061 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (System.gc()) [PSYoungGen: 2025K->665K(9216K)] 10225K->8874K(19456K), 0.0010182 secs] [Times: user=0.01 sys=0.00, real=0.01 secs]
[Full GC (System.gc()) [PSYoungGen: 665K->0K(9216K)] [ParOldGen: 8208K->594K(10240K)] 8874K->594K(19456K), [Metaspace: 2679K->2679K(1056768K)], 0.0052985 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
堆信息
Heap
PSYoungGen total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614920,0x00000007bfe00000)
from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
to space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
ParOldGen total 10240K, used 596K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
object space 10240K, 5% used [0x00000007bec00000,0x00000007bec950e8,0x00000007bf600000)
Metaspace used 2683K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 288K, capacity 386K, committed 512K, reserved 1048576K
-XX:+UseParallelOldGC
垃圾回收器: Parallel Scavenge+Parallel Old
GC 日志
[GC (Allocation Failure) [PSYoungGen: 7884K->729K(9216K)] 16076K->8930K(19456K), 0.0018887 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [PSYoungGen: 8061K->713K(9216K)] 16261K->8914K(19456K), 0.0014337 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
[GC (System.gc()) [PSYoungGen: 2057K->633K(9216K)] 10257K->8842K(19456K), 0.0010012 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [PSYoungGen: 633K->0K(9216K)] [ParOldGen: 8208K->594K(10240K)] 8842K->594K(19456K), [Metaspace: 2679K->2679K(1056768K)], 0.0047913 secs] [Times: user=0.01 sys=0.00, real=0.00 secs]
堆信息
Heap
PSYoungGen total 9216K, used 82K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
eden space 8192K, 1% used [0x00000007bf600000,0x00000007bf614920,0x00000007bfe00000)
from space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
to space 1024K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007c0000000)
ParOldGen total 10240K, used 596K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
object space 10240K, 5% used [0x00000007bec00000,0x00000007bec950e8,0x00000007bf600000)
Metaspace used 2684K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 288K, capacity 386K, committed 512K, reserved 1048576K
-XX:+UseConcMarkSweepGC
垃圾回收器: ParNew+CMS
GC 日志
[GC (Allocation Failure) [CMS: 8192K->600K(10240K), 0.0039740 secs] 9932K->600K(19456K), [Metaspace: 2677K->2677K(1056768K)], 0.0040636 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [ParNew: 7331K->0K(9216K), 0.0005220 secs] 12028K->4696K(19456K), 0.0005620 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[Full GC (System.gc()) [CMS: 4696K->599K(10240K), 0.0022873 secs] 7932K->599K(19456K), [Metaspace: 2678K->2678K(1056768K)], 0.0023498 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
堆信息
Heap
par new generation total 9216K, used 82K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)
eden space 8192K, 1% used [0x00000007bec00000, 0x00000007bec14920, 0x00000007bf400000)
from space 1024K, 0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)
to space 1024K, 0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000)
concurrent mark-sweep generation total 10240K, used 600K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)
Metaspace used 2683K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 288K, capacity 386K, committed 512K, reserved 1048576K