20210520 使用jstat分析垃圾收集状况

Posted 陈如水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20210520 使用jstat分析垃圾收集状况相关的知识,希望对你有一定的参考价值。

常用命令:

jstat -gcutil <pid> 1000

gc垃圾回收信息

gcXXX各区域GC的详细信息,如-gcold

Java 堆分为新生代和老年代,新生代一般划分为三块区域,Eden + From Survivor + To Survivor,Eden 和 Survivor 的内存比为8:1,每次只使用一个Eden 和一个 Survivor 区域,另一个 Survivor 用于复制收集算法回收内存。

对象一般尽量分配到新生代中,而对于大对象(长字符串和大数组)直接分配在老年代中,同时“年龄”长的的对象会从新生代自动晋升到老年代中。

当 Eden 区域分配不足时,自动发生一次 Minor GC。

当发生 Minor GC 时,虚拟机会自动检测(比较)新生代晋升到老年代的对象内存大小和老年代剩余内存大小,如果晋升>剩余,则发生一次Full GC;如果晋升

YGC: 从应用程序启动到当前,发生Yang GC 的次数

YGCT: 从应用程序启动到当前,Yang GC所用的时间【单位秒】

FGC: 从应用程序启动到当前,发生Full GC的次数

FGCT: 从应用程序启动到当前,Full GC所用的时间

GCT: 从应用程序启动到当前,用于垃圾回收的总时间【单位秒】

 

1) 从应用程序启动到当前;

2) 触发YGC的条件;

3) 触发FGC的条件;

4) 垃圾回收的时间,单位是秒;

5) Eden区域满了以后才会触发一次YGC。

 

出现cpu突然飙升的可能原因

1)死循环,或者大量for循环;

2)大量的gc正在被触发;(例如:每秒执行一次gc) 

 

一直在触发FULL GC的可能原因

 年轻代到年老代的晋升不断被触发,年轻代空间不够用。

 

应用服务器(java)莫名其妙的出现被kill掉现象。应用进程被杀掉。

可能的原因:Java应用程序的问题:发生OOM导致进程Crash

一般情况下,出现OOM异常,JVM的GC会进行回收,是不会直接导致JVM进程退出的。如果出现退出的情况,那就是内存泄漏,由于内存占用越来越大,结果操作系统杀掉进程。

 

现象:出现CPU飙升的情况,要么走到了死循环,要么就是在做大量的GC。使用jstat -gc pid [interval]命令查看了java进程的GC状态,果然,FULL GC达到了每秒一次。

这么多的FULL GC,应该是内存泄漏没跑了,于是使用jstack pid > jstack.log保存了线程栈的现场。

一直在触发FULL GC,说明了什么问题?年轻代没内存了,为什年轻代没内存了?

线上应用宕机。紧急排查发现应用的的进程已经不在了,怀疑是因为内存占用过多导致被操作系统杀进程了。接着查看操作系统日志,如下,果然发现是因为内存占用高达8G而被系统直接杀进程。

CPU满载

应用重启后,刚开始几分钟很正常,但是很快监控报警CPU占用过高,并且应用很快不再响应外部的任何请求,所有的HTTP请求全部阻塞直到网关超时。

通过top命令立即定位到CPU占用高的进程正是刚刚重启的应用。然后通过命令,来定位java应用是那个线程占用CPU过高.

CPU占用高的并不是用户线程,而是JVM的线程,怀疑是不是GC出了问题。

如何区分用户线程还是jvm线程?

以上是关于20210520 使用jstat分析垃圾收集状况的主要内容,如果未能解决你的问题,请参考以下文章

jstat命令

20210520 使用jmap分析虚拟机内存状况

20210520 使用jmap分析虚拟机内存状况

永久代溢出(java.lang.OutOfMemoryError: PermGen space )

jvm2

JAVA程序分析工具jstat和jstack