不可思议,竟然还有人不会查看GC垃圾回收日志?
日志的重要性,不需要过多强调了。通过日志,我们可以发现程序可能有内存(泄露)问题。本文从案例出发,具体介绍这些日志信息,以期帮助大家更好地了解垃圾回收的运行情况。
还是先上图,看看本文的主要内容:
我们先来看个案例,代码如下:
/**
* 打印垃圾回收日志案例
* 参数设置: -XX:+PrintGCDetails
* @author 田维常
* @version 1.0
* @date 2020/11/9 8:22
*/
public class PrintGCDetailsDemo {
public static void main(String[] args) {
System.out.println("Hello world");
}
}
启动参数设置:
XX:+PrintGCDetails
运行main方法,输出
Hello world
Heap
PSYoungGen total 38400K, used 4670K [0x00000000d5f00000, 0x00000000d8980000, 0x0000000100000000)
eden space 33280K, 14% used [0x00000000d5f00000,0x00000000d638fb98,0x00000000d7f80000)
from space 5120K, 0% used [0x00000000d8480000,0x00000000d8480000,0x00000000d8980000)
to space 5120K, 0% used [0x00000000d7f80000,0x00000000d7f80000,0x00000000d8480000)
ParOldGen total 87552K, used 0K [0x0000000081c00000, 0x0000000087180000, 0x00000000d5f00000)
object space 87552K, 0% used [0x0000000081c00000,0x0000000081c00000,0x0000000087180000)
Metaspace used 3525K, capacity 4498K, committed 4864K, reserved 1056768K
class space used 388K, capacity 390K, committed 512K, reserved 1048576K
关于GC日志的参数
-XX:+PrintGC 输出GC日志
-XX:+PrintGCDetails 输出GC的详细日志
-XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息
-Xloggc:../logs/gc.log 日志文件的输出路径
参数案例
-XX:+PrintGCDetails
-XX:-UseAdaptiveSizePolicy
-XX:SurvivorRatio=8
-XX:NewSize=10M -XX:MaxNewSize=10M
参数解释:
-XX:+PrintGCDetails
启用日志
-XX:-UseAdaptiveSizePolicy
禁用动态调整,使SurvivorRatio
可以起作用
-XX:SurvivorRatio=8
设置Eden:Survivior
=8:1
-XX:NewSize=10M -XX:MaxNewSize=10M
设置整个新生代的大小为10M
写了一个Spring Boot项目,非常简单的项目,里面写了一个controller
package com.tian.my_code.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* @author 田维常
* @version 1.0
* @date 2020/11/8 15:46
*/
@RestController
public class GCController {
List<Object> strings = new ArrayList<>();
@GetMapping("/gc")
public String addObject() {
System.out.println("-------gc-------");
for (int i = 0; i < 1000000; i++){
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
int [] a=new int[500000];
strings.add(a);
}
return "ok";
}
}
这段代码其实是想后面演示OOM
用的,都行吧,这里先用他来看看GC
垃圾回收日志。
在IDEA中设置
输出结果
抓出一段来聊聊
GC (minor )日志
[GC (Allocation Failure)
[PSYoungGen: 8525K->352K(9216K)] 98695K->98486K(130048K),
0.0092873 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]
(Allocation Failure):表明本次引起
GC
的原因是因为在年轻代中没有足够的空间能够存储新的数据了。
PSYoungGen
:表示是GC
类型
8525K
:YoungGC
前新生代内存占用
352K
:YoungGC
新生代内存占用9216K:新生代总共大小
98695K:YoungGC前JVM内存占用
98486K:YoungGC后JVM内存使用
130048K:JVM堆总大小
0.0092873 secs
:YoungGC
耗时
user=0.00
:YoungGC
用户耗时
sys=0.00
:YoungGC
系统耗时real=
0.01:YoungGC
实际耗时(这里居然四舍五入了)
Full GC 日志
[Full GC (Ergonomics)
[PSYoungGen: 8051K->7817K(9216K)]
[ParOldGen: 244969K->244969K(245760K)] 253020K->252786K(254976K),
[Metaspace: 29386K->29386K(1077248K)], 0.0525381 secs]
[Times: user=0.13 sys=0.00, real=0.05 secs]
PSYoungGen: 8051K->7817K(9216K)
:新生代区GC
前后和总大小
ParOldGen: 244969K->244969K(245760K)
:老年代GC
前后和大小。
253020K->252786K(254976K)
:堆GC
前后内存占用情况。
Metaspace: 29386K->29386K(1077248K)
:元空间GC
前后和总大小后面那几项和上面一样
GC垃圾回收日志就是这么简单么~蓝(nan)不蓝(nan)?