GC监控 6.1 JDK自带工具监控 6.1.1 jps 说明:列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main()函数所在的类)的名称,以及这些进程的本地虚拟机的唯一ID(LVMID,Local Virtual Machine Identifier) 语法:jps [option] [hostid] 语法说明: 6.1.2 jstat 说明:用于监控虚拟机各种运行状态信息的命令行工具。它可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据 语法:jstat [option vmid [interval[s|ms] [count]] ] 语法说明: 6.1.3 jinfo 说明:作用是实时地查看和调整虚拟机的各项参数。使用jps的命令的-v参数可以查看虚拟机启动时显示指定的参数列表,但如果想知道未被显示指定的参数的系统默认值,除了去找资料外,就只能使用jinfo的-flag选项进行查询 6.1.4 jmap 说明:用于生产堆转储快照(一般称为heapdump或dump文件),还可以查询finalize执行队列,Java堆和永久代的详细信息,如空间使用率、当前用的是那种收集器 语法:jmap [option] vmid 语法说明: 6.1.5 jhat 说明:与jmap搭配使用,来分析jmap生成的堆转储快照 6.1.6 jstack 说明:用于生成虚拟机当前时刻的线程快照(一般称为threaddump或javacore文件)。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的常见原因 6.2 可视化软件监控 6.2.1 JConsole 位置:JAVA_HOME/bin/ 6.2.2 Visual JVM 位置:JAVA_HOME/bin/ 功能比JConsole强大 说明:安装相关插件如Visual GC之后,可以用于显示虚拟机进程及进程的配置和环境信息(jps,jinfo),监视应用程序的CPU、GC、堆、方法区及线程的信息(jstat、jstack) 6.3 GC日志分析 6.3.1 开启GC日志 —-在JVM启动参数中添加-verbose:gc -Xloggc:D:/tomcat_gc.log -XX:+PrintGCDetails -XX:+PrintGCTimeStamps —-打印样例:2.002: [GC [PSYoungGen: 46080K->7677K(53760K)] 46080K->9721K(186880K), 0.0109905 secs] [Times: user=0.03 sys=0.00, real=0.01 secs] —-参数说明: -verbose:gc:打印简单GC信息,例如[GC 72104K->9650K(317952K), 0.0130635 secs] -XX:+PrintGCDetails:打印详细GC信息,例如[GC [PSYoungGen: 46080K->7677K(53760K)] 46080K->9721K(186880K), 0.0109905 secs] -XX:+PrintGCTimeStamps 输出GC的时间戳(以基准时间的形式,例如上一行中的2.002) -XX:+PrintGCDateStamps 输出GC的时间戳(以日期的形式,如 2017-07-04T21:53:59.234+0800,比TimeStamps要详细) -XX:+PrintHeapAtGC 在进行GC的前后打印出堆的信息 -Xloggc: path/gc.log 日志文件的输出路径 —-GC监控:一般使用-Xloggc、-XX:+PrintGCDetails、-XX:+PrintGCDateStamps 6.3.2 分析GC日志 打印样例:2.002: [GC [PSYoungGen: 46080K->7677K(53760K)] 46080K->9721K(186880K), 0.0109905 secs] [Times: user=0.03 sys=0.00, real=0.01 secs] (1)2.002:时间戳 (2)[PSYoungGen: 46080K->7677K(53760K)]:年轻代GC回收前大小—>回收后大小(总大小) (3)46080K->9721K(186880K):整个堆GC回收前大小—>回收后大小(总大小) (4)0.0109905 secs:Minor GC耗费时间 (5)[Times: user=0.03 sys=0.00, real=0.01 secs]:real表示GC实际耗费时间,user表示耗费所有CPU时间总和。注意在SerialGC中只有一个线程(CPU)执行GC,所以user=real,但是在Parallel GC中,有多个CPU参与GC,所以相对于Serial GC,real会缩短,user会增大
什么是Full GC:Full GC是对年轻代、年老代,以及持久代的统一回收,由于是对整个空间的回收,因此比较慢,系统中应当尽量减少Full GC的次数 什么时候发生Full GC: (1) 年老代不足 (2) 持久代不足 (3) 显式调用system.gc();(可以DisableExplicitGC来禁止) 什么是OOM:(java.lang.OutOfMemoryError: Java heap space)、(java.lang.OutOfMemoryError: Java Perm space) 什么时候抛出OOM: 在JVM中如果98%时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息
总结 (1)GC调优没有公式可循,唯一的办法是实验 (2)默认GC:如果没有刻意设置JVM参数,默认是使用Parallel GC