说到 Java 虚拟机,不得不提的就是 Java 虚拟机的 GC(Garbage Collection)日志。而对于 GC 日志,我们不仅要学会看懂,而且要学会如何设置对应的 GC 日志参数。今天就让我们来学习一下 Java 虚拟机中所有与 GC 日志有关的参数。相信掌握了这些参数之后,对于大家线上打印 GC 日志是有不少帮助的。

为了能够更直观地显示出每个参数的作用,我们将以下面的 Demo 为例子去设置 GC 日志参数。

/*** @author 陈树义* @date 2018.09.29*/
public class GCDemo {public static void main(String[] args) {// allocate 4M spacebyte[] b = new byte[4 * 1024 * 1024];System.out.println("first allocate");// allocate 4M spaceb = new byte[4 * 1024 * 1024];System.out.println("second allocate");}
}

在上面的程序中,我们两次分配了 4M 的内存空间。为了认为制造 GC,我们启动时的 JVM 参数固定加上下面几个参数:

-XX:+UseSerialGC -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8
  • -XX:+UseSerialGC 表示强制使用Serial+SerialOld收集器组合
  • -Xms20m 表示堆空间初始大小为 20 M。
  • -Xmx20m 表示堆空间最大大小为 20 M。
  • -Xmn10m 表示新生代大小为 10M。
  • -XX:SurvivorRatio=8 表示Eden:Survivor=8:1

经过上面这个设置,此时我们的堆空间的内存比例情况如下:Eden区 8M,FromSurvivor 1M,ToSurvivor 1M,老年代 10M。

下面就让我们来看看油管 GC 的参数有哪些吧。

打印GC日志

在 GC 日志参数中,最简单的一个参数就是打印 GC 日志:-XX:PrintGC。我们用下面的命令运行程序:

java -XX:+UseSerialGC -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:+PrintGC com.chenshuyi.GCDemo

输出结果:

first allocate
second allocate
[GC (Allocation Failure)  4767K->4374K(19456K), 0.0045179 secs]

可以看到程序在第一次分配数组空间的时候发生了 GC,并且把 GC 前后以及堆空间大小都打印了出来。该日志显示 GC 前堆空间使用量为 4767K(4M左右)。GC 后堆空间为 4374K,当前可用堆大小为 19456K。

但你会发现使用 PrintGC 参数打印出来的日志比较简单,无法查看更详细的信息。如果你要查看更详细的信息,那么就需要下面这个参数。

打印详细GC日志

如果要查看更加详细的 GC 日志,那么就要使用 -XX:+PrintGCDetils 参数。下面我们使用该参数运行程序:

java -XX:+UseSerialGC -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:+PrintGC com.chenshuyi.GCDemo

程序输出:

first allocate
second allocate
[GC (Allocation Failure) [DefNew: 4603K->278K(9216K), 0.0036744 secs] 4603K->4374K(19456K), 0.0037100 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heapdef new generation   total 9216K, used 4538K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)eden space 8192K,  52% used [0x00000007bec00000, 0x00000007bf0290e0, 0x00000007bf400000)from space 1024K,  27% used [0x00000007bf500000, 0x00000007bf545920, 0x00000007bf600000)to   space 1024K,   0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)tenured generation   total 10240K, used 4096K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)the space 10240K,  40% used [0x00000007bf600000, 0x00000007bfa00010, 0x00000007bfa00200, 0x00000007c0000000)Metaspace       used 2649K, capacity 4486K, committed 4864K, reserved 1056768Kclass space    used 286K, capacity 386K, committed 512K, reserved 1048576K

从上面的日志可以看出,该参数能打印出更加详细的 GC 信息,包括:年轻代的信息、永久代的信息。

[GC (Allocation Failure) [DefNew: 4603K->278K(9216K), 0.0036744 secs] 4603K->4374K(19456K), 0.0037100 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

该参数还会在退出之前打印出整个堆的详细信息:

Heapdef new generation   total 9216K, used 4538K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)eden space 8192K,  52% used [0x00000007bec00000, 0x00000007bf0290e0, 0x00000007bf400000)from space 1024K,  27% used [0x00000007bf500000, 0x00000007bf545920, 0x00000007bf600000)to   space 1024K,   0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)tenured generation   total 10240K, used 4096K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)the space 10240K,  40% used [0x00000007bf600000, 0x00000007bfa00010, 0x00000007bfa00200, 0x00000007c0000000)Metaspace       used 2649K, capacity 4486K, committed 4864K, reserved 1056768Kclass space    used 286K, capacity 386K, committed 512K, reserved 1048576K

GC前后打印堆信息

上面两个命令基本上可以应付 90% 的使用场景了,但有时候我们在 GC 前后还想获取更加详细的信息。那么我们可以使用 PrintHeapAtGC 参数,该参数会在 GC 前后打印堆信息。

使用下面的命令运行程序:

java -XX:+UseSerialGC -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:+PrintHeapAtGC com.chenshuyi.GCDemo

输出结果:

first allocate
second allocate
{Heap before GC invocations=0 (full 0):def new generation   total 9216K, used 4767K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)eden space 8192K,  58% used [0x00000007bec00000, 0x00000007bf0a7e98, 0x00000007bf400000)from space 1024K,   0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)to   space 1024K,   0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000)tenured generation   total 10240K, used 0K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)the space 10240K,   0% used [0x00000007bf600000, 0x00000007bf600000, 0x00000007bf600200, 0x00000007c0000000)Metaspace       used 2646K, capacity 4486K, committed 4864K, reserved 1056768Kclass space    used 286K, capacity 386K, committed 512K, reserved 1048576K
Heap after GC invocations=1 (full 0):def new generation   total 9216K, used 278K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000)eden space 8192K,   0% used [0x00000007bec00000, 0x00000007bec00000, 0x00000007bf400000)from space 1024K,  27% used [0x00000007bf500000, 0x00000007bf545950, 0x00000007bf600000)to   space 1024K,   0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000)tenured generation   total 10240K, used 4096K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000)the space 10240K,  40% used [0x00000007bf600000, 0x00000007bfa00010, 0x00000007bfa00200, 0x00000007c0000000)Metaspace       used 2646K, capacity 4486K, committed 4864K, reserved 1056768Kclass space    used 286K, capacity 386K, committed 512K, reserved 1048576K
}

仔细看一下,会发现在 GC 发生前后都打印了一次堆空间信息。

通过这个参数,我们可以详细了解每次 GC 时堆空间的详细信息。

打印GC发生的时间 -XX:+PrintGCTimeStamps

这个参数非常简单,就是在每次 GC 日志的前面加上一个时间戳。这个时间戳表示 JVM 启动后到现在所逝去的时间。

使用下面的参数运行程序:

java -XX:+UseSerialGC -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:+PrintGC -XX:+PrintGCTimeStamps com.chenshuyi.GCDemo

输出结果:

first allocate
second allocate
0.130: [GC (Allocation Failure)  4767K->4374K(19456K), 0.0051351 secs]

上面日志第 3 行中的「0.130」就是该 GC 发生的时间。

-XX:+PrintGCApplicationConcurrentTime 打印应用程序的执行时间

使用下面的命令运行程序:

java -XX:+UseSerialGC -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:+PrintGC -XX:+PrintGCApplicationConcurrentTime com.chenshuyi.GCDemo

运行结果:

first allocate
second allocate
Application time: 0.0371892 seconds
[GC (Allocation Failure)  4767K->4374K(19456K), 0.0040074 secs]
Application time: 0.0010712 seconds

-XX:+PrintGCApplicationStoppedTime 打印应用由于GC而产生的停顿时间

使用下面的命令运行程序:

java -XX:+UseSerialGC -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:+PrintGC -XX:+PrintGCApplicationStoppedTime com.chenshuyi.GCDemo

运行结果:

first allocate
second allocate
[GC (Allocation Failure)  4767K->4374K(19456K), 0.0045644 secs]
Total time for which application threads were stopped: 0.0047873 seconds, Stopping threads took: 0.0000329 seconds

可以看到最后一行打印出了因为 GC 而暂停的时间。

保存GC日志 -Xloggc

这个参数可以将 GC 日志输出到文件中保存起来。

使用下面的参数运行程序:

java -XX:+UseSerialGC -Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:+PrintGC -XX:+PrintReferenceGC -Xloggc:gc.log com.chenshuyi.GCDemo

运行之后在本目录会生成一个 gc.log 文件,打开该文件:

Java HotSpot(TM) 64-Bit Server VM (25.181-b13) for bsd-amd64 JRE (1.8.0_181-b13), built on Jul  7 2018 01:02:31 by "java_re" with gcc 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Memory: 4k page, physical 8388608k(45132k free)/proc/meminfo:CommandLine flags: -XX:InitialHeapSize=20971520 -XX:MaxHeapSize=20971520 -XX:MaxNewSize=10485760 -XX:NewSize=10485760 -XX:+PrintGC -XX:+PrintGCTimeStamps -XX:+PrintReferenceGC -XX:SurvivorRatio=8 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseSerialGC
0.124: [GC (Allocation Failure)  4767K->4374K(19456K), 0.0047748 secs]

可以看到堆的相关信息,以及 GC 的信息。

总结

除了上面这些参数,还有可以查看弱引用的参数:-XX:+PrintReferenceGC。它跟踪软引用、弱引用、虚引用和Finallize队列的信息,但是使用场景较为狭窄。基本上掌握上面的几个常用的 GC 日志参数就足够排查使用,最重要的是弄清楚每个参数的作用和用法。

最后用列表的形式总结一下,加深一下印象。

参数 含义
-XX:PrintGC 打印GC日志
-XX:+PrintGCDetails 打印详细的GC日志。还会在退出前打印堆的详细信息。
-XX:+PrintHeapAtGC 每次GC前后打印堆信息。
-XX:+PrintGCTimeStamps 打印GC发生的时间。
-XX:+PrintGCApplicationConcurrentTime 打印应用程序的执行时间
-XX:+PrintGCApplicationStoppedTime 打印应用由于GC而产生的停顿时间
-XX:+PrintReferenceGC 跟踪软引用、弱引用、虚引用和Finallize队列。
-XLoggc 将GC日志以文件形式输出。

  • JVM基础系列开篇:为什么要学虚拟机?
  • JVM基础系列第1讲:Java 语言的前世今生
  • JVM基础系列第2讲:Java 虚拟机的历史
  • JVM基础系列第3讲:到底什么是虚拟机?
  • JVM基础系列第4讲:从源代码到机器码,发生了什么?
  • JVM基础系列第5讲:字节码文件结构
  • JVM基础系列第6讲:Java虚拟机内存结构
  • JVM基础系列第7讲:JVM类加载机制
  • JVM基础系列第8讲:JVM 垃圾回收机制
  • JVM基础系列第9讲:JVM垃圾回收器
  • JVM基础系列第10讲:垃圾回收的几种类型
  • JVM基础系列第11讲:JVM参数之堆栈空间配置
  • JVM基础系列第12讲:JVM参数之查看JVM参数
  • JVM基础系列第13讲:JVM参数之追踪类信息
  • JVM基础系列第14讲:JVM参数之GC日志配置
  • JVM基础系列第15讲:JDK性能监控命令

JVM基础系列第14讲:JVM参数之GC日志配置相关推荐

  1. JVM基础系列第7讲:JVM 类加载机制

    当 Java 虚拟机将 Java 源码编译为字节码之后,虚拟机便可以将字节码读取进内存,从而进行解析.运行等整个过程,这个过程我们叫:Java 虚拟机的类加载机制.JVM 虚拟机执行 class 字节 ...

  2. JVM基础系列第10讲:垃圾回收的几种类型

    我们经常会听到许多垃圾回收的术语,例如:Minor GC.Major GC.Young GC.Old GC.Full GC.Stop-The-World 等.但这些 GC 术语到底指的是什么,它们之间 ...

  3. STM32 基础系列教程 14 - IIC

    前言 学习stm32 IIC接口的使用,用IIC 接口实现与IIC设备的通信功能. 示例详解 基于硬件平台: STM32F103C8T6最小系统板, MCU 的型号是 STM32F103c8t6, 使 ...

  4. 【Java 虚拟机原理】垃圾回收算法 ( 设置 JVM 命令参数输出 GC 日志 | GC 日志输出示例 | GC 日志分析 )

    文章目录 一.设置 JVM 命令参数输出 GC 日志 二.GC 日志示例 三.GC 日志分析 一.设置 JVM 命令参数输出 GC 日志 在 IntelliJ IDEA 的启动参数中设置 -XX:+P ...

  5. JVM面试(四)-垃圾回收、垃圾收集器、GC日志

    垃圾回收.垃圾收集器.GC日志 什么是垃圾?(垃圾的概念) 什么是垃圾回收?(垃圾回收的概念) 为什么要垃圾回收?(垃圾回收的原因) 如何定义垃圾? 引用计数算法 什么是循环引用 可达性分析算法 哪些 ...

  6. java 程序执行后 强制gc_【GC系列】JVM的常用GC参数及GC日志解析

    今天继续GC系列第三篇,熬夜不易,欢迎一键三连,给个鼓励,不点赞也没关系,我还可以,谢谢捧场[捂脸]. 常见垃圾回收器组合设定 在oracle官网上可以看到如何开启使用指定垃圾回收的命令: https ...

  7. JVM基础系列开篇:为什么要学虚拟机?

    跟许多人一样,我一开始接触 Java 虚拟机只是因为面试需要用到,所以硬着头皮看看.所以很多人对于为什么要学虚拟机这个问题,他们的答案都是:因为面试.但我经过了几年的学习和实战,我发现其实学习虚拟机并 ...

  8. 【Java基础系列教程】第二章 Java语言概述、配置环境变量

    一.计算机编程语言概述 1.1 语言 语言(英文:Language)是人类进行沟通交流的表达方式.例如:中国人与中国人用普通话沟通.而中国人要和英国人交流,就要学习英语.              语 ...

  9. Kafka基础系列第1讲:Kafka的诞生背景及应用

    Kafka 是由 LinkedIn 开发的一个分布式的消息系统,使用 Scala 编写,它以可水平扩展和高吞吐率而被广泛使用.目前越来越多的开源分布式处理系统如 Cloudera.Apache Sto ...

最新文章

  1. 来认识世界上第一支AI基金:模仿股票分析师 365天无间断工作
  2. 1.14 Stream操作Collection集合
  3. 【PAT乙级】1039 到底买不买 (20 分)
  4. 【转】Pycharm创建py文件时自定义头部模板
  5. mysql keepalive_mysql主从之keepalive+MySQL高可用
  6. Tomcat - Springboot启动的时候初始化的线程池默认配置
  7. MySQL索引原理及慢查询优化,了解一下?
  8. 这4款甘特图绘制工具,都是老原精心整理
  9. [配套工具] 【新手福音】最简单的大漠插件注册方法 只需四行代码 每行附有详细说明
  10. 39份AICon全球人工智能与机器学习技术大会 · 北京站2021(PPT汇总)
  11. vue项目使用eslint和prettier格式化项目
  12. 灰度图片及彩色图片像素点统计及显示
  13. 【报告分享】快手男性消费用户洞察-36Kr磁力引擎(附下载)
  14. 从用AI+VR虚拟教室穿越到中国说起,看红头文件下,互联网教育公司的AI招牌
  15. 三位如花女人的多彩理财生活
  16. 余弦相似度-C#代码实现
  17. oracle查询部门名称,oracle查询习题(一)
  18. OpenStack Ironic实现裸机部署
  19. wordpress编辑器遇到了未知错误
  20. 重装Intel核显后,设备管理器英特尔显卡属性这里报告了一个未启动设备(igfx)

热门文章

  1. 速卖通运营之商品结构及分层逻辑
  2. 2022年全球及中国商用多旋翼无人机行业十四五战略目标与发展方向分析报告
  3. 中国定制家具行业消费规模与发展形势分析报告2022版
  4. 全球及中国生物柴油行业产量规模及市场消费需求预测报告2021-2027年
  5. COM笔记-CoCreateInstance
  6. 软件Release版本异常捕获程序(BugReport)
  7. mysql 经纬度距离 自定义函数_mysql 经纬度计算距离 自定义函数
  8. resetroot_169route_python2(用于ubuntu12.04和14.04,centos系列)
  9. Vuejs发送Ajax请求
  10. POJ - 1961 最小循环节