一、基本情况
jstat(JVM Statistics Monitoring Tool):用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。
在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。
官方文档:
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html
二、基本语法
它的基本使用语法为:
jstat -
2.1、option参数
选项option可以由以下值构成。
- 类装载相关的:
- -class: 显示ClassLoader的相关信息:类的装载、卸载数量、总空间、类装载所消耗的时间等
- 垃圾回收相关的:
- -gc: 显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、永久代等的容量、己用空间、GC时间合计等信息。
- S0C:新生者0区容量,S1C:新生者1区容量,S0U:新生者0区已使用的容量,S1U:新生者1区已使用的容量
- EC:伊甸园区总容量,EU:伊甸园已使用的容量
- OC:老年代总容量,OU:老年代已使用的容量
- MC:方法区总容量,MU:方法区已使用的容量
- CCSC:压缩类的总容量,CCSU:压缩类已使用的容量
- YGC:发生young GC的次数,YGCT:young GC消耗的时间
- FGC:Full GC次数,FGCT:Full GC消耗的时间,GCT:总GC时间
- -gccapacity: 显示内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间。
- -gcutil: 显示内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比。
- -gccause: 与 -gcutil 功能一样,但是会额外输出导致最后一次或当前正在发生的GC产生的原因。
- -gcnew: 显示新生代GC状况
- -gcnewcapacity: 显示内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间
- -geold: 显示老年代GC状况
- -gcoldcapacity: 显示内容与-gcold基本相同,输出主要关注使用到的最大、最小空间
- -gcpermcapacity: 显示永久代使用到的最大、最小空间。
- -gc: 显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、永久代等的容量、己用空间、GC时间合计等信息。
- JIT相关的:
loaded | Bytes | Unloaded | Bytes | Time |
---|---|---|---|---|
加载类的个数 | 加载当前类的所占用的字节数 | 卸载类的个数 | 卸载类所占用的字节数 | 总耗时 |
-compiler: 显示JIT编译器编译过的方法、耗时等信息
-printcompilation: 输出已经被JIT编译的方法
-gc: 显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、永久代等的容量、己用空间、GC时间合计等信息。
package studies.jvm.jps;
import java.util.ArrayList;
/**
* @Date: 2021/5/10
* @Time: 19:49
* @BelongsProject base
* @BelongsPackage studies.jvm.jps
* @Description: -Xms60m -Xmx60m -XX:SurvivorRatio=8
*/
public class GCTest {
public static void main(String[] args) {
ArrayList<byte[]> list = new ArrayList<>();
for (int i = 0; i < 1000; i++){
byte[] arr = new byte[1024 * 100];//100kb
list.add(arr);
try {
Thread.sleep(120);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
内存设置的大小为60M,新生代默认比例为2(newRatio=2),新生代20M,老年代40M。因为设置了SurvivorRatio=8,那新生代中S0C为2M,S1C为2M,伊甸园区占16M
2.2、interval参数
用于指定输出统计数据的周期,单位为毫秒。即:查询间隔
每隔一秒打印一次
2.3、count参数
用于指定查询的总次数
不加interval和count默认只查一次
2.4、-t参数
可以在输出信息前加上一个Timestamp列,显示程序的运行时间。单位:秒
显示程序运行的总时间
经验:
我们可以比较Java进程的启动时间以及总 GC 时间(GCT 列),或者两次测量的间隔时间以及总GC时间的增量,来得出GC时间占运行时间的比例。
如果该比例超过20%,则说明目前堆的压力较大;如果该比例超过90%,则说明堆里几乎没有可用空间,随时都可能抛出OOM异常。
2.5、-h参数
可以在周期性数据输出时,输出多少行数据后输出一个表头信息
-h2是每两条数据都打印一次表头
三、补充
jstat还可以用来判断是否出现内存泄漏。
第1步:
在长时间运行的Java程序中,我们可以运行jstat命令连续获取多行性能数据,并取这几行数据中 OU列(即已占用的老年代内存)的最小值。
第2步:
然后,我们每隔一段较长的时间重复一次上述操作,来获得多组OU最小值。如果这些值呈上涨趋势,则说明该Java程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄漏。