JVM系列文章目录
GC调优基础知识工具篇之JDK自带工具
前言
本文基于JDK1.8,是博主个人的JVM学习记录,欢迎各位指正错误的地方。
JDK命令行工具
jps
列出当前机器上运行的JVM进程,由于JPS是在临时目录上查找到,所以有些信息可能显示不全。
参数:
- -q:仅显示进程。
- -m:输出主函数传入的参数。
- -l:输出应用程序烛泪完整package名称或者jar的完整名称。
- -v:列出JVM参数(启动程序是指定的JVM参数)。
jstat
这个是监控虚拟机各个进程的运行信息的。
它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT 编译等运行数据,在没有 GUI 图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。
比如统计GC。
参数:
-
-class :类加载器。
-
-compiler :JIT。
-
-gc :GC 堆状态。
-
-gccapacity :各区大小。
-
-gccause :最近一次 GC 统计和原因。
-
-gcnew :新区统计。
-
-gcnewcapacity :新区大小。
-
-gcold :老区统计。
-
-gcoldcapacity :老区大小。
-
-gcpermcapacity :永久区大小。
-
-gcutil: GC 统计汇总。
-
-printcompilation :HotSpot 编译统计)。
示例:
示例参数说明:
- S0C:第一个幸存区(From 区)的大小 。
- S1C:第二个幸存区(To 区)的大小。
- S0U:第一个幸存区的使用大小 。
- S1U:第二个幸存区的使用大小 。
- EC:伊甸园(Eden)区的大小。
- EU:伊甸园(Eden)区的使用大小 。
- OC:老年代大小。
- OU:老年代使用大小 。
- MC:方法区大小 。
- MU:方法区使用大小 。
- CCSC:压缩类空间大小 。
- CCSU:压缩类空间使用大小 。
- YGC:年轻代垃圾回收次数 。
- YGCT:年轻代垃圾回收消耗时间 。
- FGC:老年代垃圾回收次数 。
- FGCT:老年代垃圾回收消耗时间 。
- GCT:垃圾回收消耗总时间。
jinfo
查看和修改虚拟机参数(这个修改参数指的是可被修改的参数)。
- –sysprops 可以查看由 System.getProperties()取得的参数 。
- –flag 未被显式指定的参数的系统默认值 。
- –flags 显示虚拟机的参数。
JVM参数分类
- 标准选项:
-
开头,所有的JVM都支持这种选项,即这种选项参数在各个JVM上都能用。它们用于执行常见操作,例如检查 JRE 版本,设置类路径,启用详细输出等。 - 非标准选项:
-X
开头,特定版本的Hotspot虚拟机的通用选项,在别的JVM上不一定支持,并且它们的指令可能发生变化。如:-Xms30m -Xmx30m -Xss1m
。 - 高级选项:
-XX
开头,这类选项是提供给开发人员使用的,用来调整Hotsopt的特定区域,这些区域通常具有特定的系统要求,并且可能需要对系统配置参数的特权访问。也 不能保证所有 JVM 实现都支持它们,并且它们可能会发生变化。可以通过java -XX:+PrintFlagsFinal –version
查询所有`-XX指令
示例:manageable表示运行是可变。
在未启用PrintGC时是没有打印GC信息的
现在我们使用jinfo –flag +PrintGC <pid>
启用(9080是我Java程序的进程号),发现控制台已经开始打印GC信息了
在用jinfo -flag PrintGC <pid>
查看
关闭GC日志输出jinfo -flag -PrintGC <pid>
jmap
用于生成堆转储快照(一般称为 heapdump 或 dump 文件)。 jmap 的作用并不仅仅是为了获取 dump 文件,它还可以查询 finalize 执行队列、Java 堆和永 久代的详细信息,如空间使用率、当前用的是哪种收集器等。
-
jmap –heap <pid>
打印堆信息
示例:由于mac版jdk1.8的bug,我这里使用jdk10来查看(指令与jdk1.8不同)
-
jmap –histo <pid>
打印每个 class 的实例数目,内存占用,类全名信息。
-
jmap –histo:live <pid>
如果 live 子参数加上后,只统计活的对象数量。
-
jmap -dump:live,format=b,file=heap.bin <pid>
生成堆转储快照,将堆信息,按照byte的格式,输出的到当前路径下的heap.bin文件中。注意,这个比较消耗磁盘空间,基本上你JVM堆有多大就要复制出一份多大的存储文件在磁盘中,而且会占用IO,性能也较差,所以在生产环境请小心使用。
jhat
可以在服务器上生成堆转储文件分析(一般不推荐,毕竟占用服务器的资源,比如一个文件就有 1 个 G 的话就需要大约吃一个 1G 的内存资源)。
jhat <filename>
,当输出Server is ready ,访问http://localhost:7000/就可以查看详情。
jstack
jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照。
线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主 要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致线程长时间停顿的常见原因。
一般用于排查死锁问题。
示例:
package ex10;
/**
* @author Abfeathers
* @date 2021/3/18
* @Description jstack 死锁排查
*
*/
public class NormalDeadLock {
private static Object No1 = new Object();//第一个资源
private static Object No2 = new Object();//第二个资源
//拿第二个资源的方法
private static void get2Do() throws InterruptedException {
String threadName = Thread.currentThread().getName();
synchronized (No1){
System.out.println(threadName+" get NO1");
Thread.sleep(100);
synchronized (No2){
System.out.println(threadName+" get NO2");
}
}
}
//拿第一个资源的方法
private static void get1Do() throws InterruptedException {
String threadName = Thread.currentThread().getName();
synchronized (No2){
System.out.println(threadName+" get NO2");
Thread.sleep(100);
synchronized (No1){
System.out.println(threadName+" get NO1");
}
}
}
//子线程,先拿第二个资源
private static class GetNo2 extends Thread{
private String name;
public GetNo2(String name) {
this.name = name;
}
@Override
public void run() {
Thread.currentThread().setName(name);
try {
get2Do();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
//主线程,先拿第一个资源
Thread.currentThread().setName("get1");
GetNo2 getNo2 = new GetNo2("get2");
getNo2.start();
get1Do();
}
}
使用指令jstack <pid>
直接拉到对底部查看信息:直接给你分析出了死锁
关于命令工作的参数使用推荐
生产服务器推荐开启
-
-XX:-HeapDumpOnOutOfMemoryError 默认关闭,建议开启,在 java.lang.OutOfMemoryError 异常出现时,输出一个 dump 文件,记录当时的堆内存快照。
-
-XX:HeapDumpPath=./java_pid.hprof 用来设置堆内存快照的存储文件路径,默认是 java 进程启动位置。
调优之前开启、调优之后关闭
-
-XX:+PrintGC 调试跟踪之 打印简单的 GC 信息参数。
-
-XX:+PrintGCDetails, +XX:+PrintGCTimeStamps 打印详细的 GC 信息。
-
-Xlogger:logpath 设置 gc 的日志路,如: -Xlogger:log/gc.log, 将 gc.log 的路径设置到当前目录的 log 目录下。
应用场景: 将 gc 的日志独立写入日志文件,将 GC 日志与系统业务日志进行了分离,方便开发人员进行追踪分析。
考虑使用
-
-XX:+PrintHeapAtGC, 打印推信息 参数设置: -XX:+PrintHeapAtGC 应用场景: 获取 Heap 在每次垃圾回收前后的使用状况
-
-XX:+TraceClassLoading 参数方法: -XX:+TraceClassLoading 应用场景: 在系统控制台信息中看到 class 加载的过程和具体的 class 信息,可用以分析类的加载顺序以及是否可进行精简操作。
-
-XX:+DisableExplicitGC 禁止在运行期显式地调用 System.gc()。
JDK可视化工具
jconsole
可以直接连接本地或者远程(远程一般生产环境不会给你开启端口,所以可视化工具在自己本地玩一玩就好了)。
命令行直接输入jconsole
,选择一个进程进行连接
内容基本上都能直接看明白,这里就不仔细描述了。
jvisualvm
这个跟jconsole类似,也是命令行输入jvisualvm
即可
上一篇:Java语法糖及底层实现)