JDK命令
以下介绍的JDK命令主要是处理应用程序性能问题、定位程序故障等情况。
JDK监控和故障处理工具
名称 | 主要作用 |
---|---|
jps | 显示指定系统内所有的HotSpot虚拟机进程 |
jstat | 收集HotSpot虚拟机各方面的运行数据 |
jinfo | 显示虚拟机配置信息 |
jmap | 生成虚拟机的内存转储快照(heapdump文件) |
jhat | 分析heapdump文件,会建立一个HTTP/HTML服务器,让用户可以在浏览器查看分析结果 |
jstack | 显示细腻的线程快照 |
jps:虚拟机进程状况工具
JVM Process Status Tool,显示指定系统内所有的虚拟机进程。列出正在运行的细腻及进程,并显示虚拟机执行主类以及这些进程的本地虚拟机唯一ID。类似ps。
-q:只输出进程 ID
-m:输出传入 main 方法的参数
-l:输出完全的包名,应用主类名,jar的完全路径名
-v:输出jvm参数
-V:输出通过flag文件传递到JVM中的参数
与ps区别:启动多个虚拟机进程时,无法根据进程名称定位时,只能依赖jps命令显示主类的功能区分。
jstat:虚拟机统计信息监视工具
JVM Statistics Monitoring Tool,用于收集虚拟机各方面的运行数据。可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。
-class 显示ClassLoad的相关信息;
-compiler 显示JIT编译的相关信息;
-gc 显示和gc相关的堆信息;
-gccapacity 显示各个代的容量以及使用情况;
-gcmetacapacity 显示metaspace的大小
-gcnew 显示新生代信息;
-gcnewcapacity 显示新生代大小和使用情况;
-gcold 显示老年代和永久代的信息;
-gcoldcapacity 显示老年代的大小;
-gcutil 显示垃圾收集信息;
-gccause 显示垃圾回收的相关信息(通-gcutil),同时显示最后一次或当前正在发生的垃圾回收的诱因;
-printcompilation 输出JIT编译的方法信息;
解析:jstat -gc 13504 2000 20(每隔2秒监控一次,共做10次)
名称 | 主要作用 |
---|---|
S0C,S1C | survivor space 幸存区0,1当前空间大小 |
S0U,S1U | survivor space 幸存区0,1使用空间大小 |
EC | Eden space 伊甸园当前空间大小 |
EU | Eden space 伊甸园使用空间大小 |
OC | Old space老年代当前空间大小 |
OU | Old space老年代使用空间大小 |
MC | Metaspace 元空间总空间大小 |
MU | Metaspace 元空间使用空间大小 |
CCSC | 压缩类空间大小 |
CCSU | 压缩类空间使用大小 |
YGC | YoungGC年轻代垃圾回收次数 |
YGCT | YoungGC年轻代垃圾回收时间 |
FGC | FullGC老年代垃圾回收次数 |
FGCT | FullGC老年代垃圾回收时间 |
GCT | 全部GC时间 |
jstat参数解析参考:https://blog.csdn.net/maosijunzi/article/details/46049117
jinfo:java配置信息工具
Configuration Info for Java,显示虚拟机配置信息。可以实时查看虚拟机的相关配置信息。
no option 输出全部的参数和系统属性
-flag name 输出对应名称的参数
-flag [+|-]name 开启或者关闭对应名称的参数
-flag name=value 设定对应名称的参数
-flags 输出全部的参数
-sysprops 输出系统属性
eg:jinfo -flags pid 描述:输出全部的参数
jmap:java内存映射工具
Memory Map for Java,生成虚拟机的内存转储快照(heapdump或dump文件)。还可以查询finalize执行队列,java堆和永久带的详细信息,如空间使用率,当前使用的哪种收集器等等。
-heap: 显示Java堆详细信息
-histo[:live]: 显示堆中对象的统计信息
-finalizerinfo: 显示在F-Queue队列等待Finalizer线程执行finalizer方法的对象
-dump::生成堆转储快照
-F:当-dump没有响应时,使用-dump或者-histo参数. 在这个模式下,live子参数无效.
eg1: jmap -heap 16840堆信息
eg2: jmap -dump:format=b,file=aa.bin 57524
jhat:虚拟机堆转储快照分析工具
JVM Heap Dump Browser,用于分析heapdump文件,建立一个Http/HTML服务器,查看分析结果。与jmap搭配使用,分析jmap生成的快照。
eg: jhat aa.bin
访问:http://localhost:7000/ 即可看到当时的快照信息,默认以包为单位显示,不常使用不做具体分析。
jstack:java堆栈跟踪工具
Stack Trace for Java,jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 Java 应用程序中线程堆栈信息。用于生成虚拟机当前时刻的线程快照(一般称为threaddump或者javacore文件)。线程快照就是当前虚拟机每一条线程正在执行的方法堆栈的集合,生成的线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁,死循环,请求外部资源导致的长时间等待等等。
-l 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent 的 ownable synchronizers列表.
-F 当’jstack [-l] pid’没有相应的时候强制打印栈信息
-m 打印java和native c/c++框架的所有栈信息.
-h | -help 打印帮助信息
jstack -F pid >> a.log
可以用其来检查死锁。线程1与线程2都只进行加锁操作,不进行释放锁。此时发生死锁现象。
ReentrantLock lock1 = new ReentrantLock();
ReentrantLock lock2 = new ReentrantLock();
Thread t1 = new Thread(() -> {
lock1.lock();
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {}
lock2.lock();
});
Thread t2 = new Thread(() -> {
lock1.lock();
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {}
lock2.lock();
});
t1.start();
t2.start();
JDK可视化工具
若当真排查问题使用命令行,那选择放弃可以不?不过,好在JDK提供了两个功能强大的可视化工具(JConsole,JVisualVM),其中JVisualVM现已成为Oracle主力推动的多合一故障处理工具,兼容JConsole。
jconsole
Jconsole (Java Monitoring and Management Console),一种基于JMX的可视化监视、管理工具。包括以下基本功能:概述、内存、线程、类、VM概要、MBean... ...
jvisualVM
VisualVM 已在JDK6.0 update 7 中自带(java启动时不需要特定参数,监控工具在bin/jvisualvm.exe),能够监控线程,内存情况,查看方法的CPU时间和内存中的对 象,已被GC的对象,反向查看分配的堆栈(如100个String对象分别由哪几个对象分配出来的)。
使用jvisualVM要做到什么:出现OOM或者内存泄漏后,可以使用它定位到具体的代码。
使用介绍:安装插件
简单介绍
1.基本信息
2.heapdump 对应命令jmap
2.threaddump对应命令jstack
问题思考:
线上如何监控内存,cpu情况?
线上如何定位OOM问题,如果是偶发,无规律,即不能通过jvisualVM监控。
生产实战演示
见我的另一篇文章生产内存溢出问题
BTrace:动态日志跟踪
BTrace是一个安全的JVM动态追踪工具,典型的使用场景是,“我要查个问题,可那个方法没有打印入口参数和返回结果日志”,“我想看某个方法的执行耗时”,“我想查看某方法如System.GC()的调用栈”等等,这些都是BTrace可以小试牛刀的地方。它的优势是,直接attach应用JVM,不用重启应用进程,可比较快速方便地定位问题。
/* BTrace Script Template */
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.BTraceUtils;
@BTrace(unsafe = true)// 表示这是一个BTrace跟踪脚本,并启用unsafe模式(因为使用了BTraceUtils以外的方法,即String.valueOf(obj))
public class TracingScript {
@OnMethod(clazz="com.example.demo.web.UserController", //类的全名
method="login",// 方法名
location=@Location(Kind.RETURN))// 表示跟踪某个类的某个方法,位置为方法返回处
public static void test(@Self com.example.demo.web.UserController self,
com.example.demo.constant.UserVo userVo,@Return String result) {
println("test start!");
jstack();
println(self);
println(String.valueOf(userVo)) ;
println(result);
println("test end!");
}
}
结果: