JVM 之常见命令
一、性能监控
1 jps 查看正在运行的进程
参数:
q
:仅仅显示虚拟机唯一id。不显示主类的名称等l
:输出应用程序主类的全类名 或 如果进程执行的是jar包,则输出jar完整路径m
:输出虚拟机进程启动时传递给主类main()的参数v
:列出虚拟机进程启动时的JVM参数。比如:-Xms20m-Xmx50m是启动程序指定的jvm参数。
说明:以上参数可以综合使用。 补充:如果某 Java 进程关闭了默认开启的UsePerfData参数(即使用参数-XX:-UsePerfData),那么jps命令将无法探知该Java 进程。
2 jstat 查看JVM的统计信息
jstat:用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据
在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。
2.1 基本语法
# -t: 显示程序的运行时间,单位秒
# -h: 周期性数据输出时,输出多少行数据后输出一个表头信息
# interval: 指定查询的间隔时间
# count: 指定查询的次数
jstat -<option> [-t] [-h<lines>] <vmid> [<interval>[<count>]]
2.2 option
- 类装载相关的:
-class
,显示ClassLoader的相关信息,类型的装载、卸载熟练、总空间、类装载所消耗的时间等。 - 垃圾回收相关的:
-gc
:显示与GC相关的信息-gccapacity
:显示内容与-gc基本相同,但输出主要关注Java堆区各个区域使用到的最大、最小空间-gcutil
:显示内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比-gccasue
:功能与gcutil一样,但额外输出导致最后一次或当前正在GC的原因-gcnew
:显示新生代GC状况-gcnewcapacity
:显示内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间-gcold
:显示老年代GC状况-gcoldcapacity
:显示内容与-gcold基本相同,输出主要关注使用到的最大、最小空间
- JIT相关的:
-compiler
:显示JIT编译器编译过的方法、耗时等信息-printcompilation
:输出已经被JIT编译的方法

3 jinfo 查看、调整虚拟机的配置参数
3.1 查看
-sysprops
:查看System.getProperties()可以获取的参数-flags
:查看曾经赋值的一些参数-flag [name]
:查看具体参数的值
3.2 修改
iinfo不仅可以查看运行时某一个]ava虚拟机参数的实际取值,甚至可以在运行时修改部分参数,并使之立即生效。 但是,并非所有参数都支持动态修改。参数只有被标记为manageable的flag可以被实时修改其实,这个修改能力是极其有限的:
查看被标记为manageable的参数
# linux环境执行
java -XX:+PrintFlagsFinal -version |grep manageable

- 针对boolean类型:jinfo -flag [+|-]具体参数 PID
- 针对非boolean类型:jinfo -flag 具体参数=参数值 PID
3.3 扩展
查看所有JVM参数启动的初始值
java -XX:+PrintFlagsInitial
查看所有JVM参数的最终值
java -XX:+PrintFlagsFinal
查看那些已经被用户或者JVM设置过详细的XX参数的名称和值
java -XX:+PrintCommandLineFlags
4 jmap 导出内存映像文件&内存使用情况
jmap(JVM Memory Map):作用一方面是获取dump文件(堆转储快照文件,二进制文件)它还可以获取目标]ava进程的内存相关信息,包括]ava堆各区域的使用情况、堆中对象的统计信息、类加载信息等。
4.1 基本语法
-dump
:生成Java堆存储快照,dump文件,-dump:live只保存堆中存活的对象jmap -dump:format=b,file=<filename.hprof> PID # 存活对象 # jmap -dump:live,format=b,file=<filename.hprof> PID
-XX:+HeapDumpOnOutOfMemoryError
:在程序发送OOM时,导出应用程序当前堆快照-XX:HeapFumpPath=<filename.hprof>
:保持堆快照地址
-heap
:输出整个堆空间的详细信息,包括GC的使用、堆配置信息,以及内存的使用信息等# 查看内存详情 jmap -heap PID # 查看内存中存活对象 jmap -heap:live PID # 将内存情况输出到文件 jmap -heap PID >xxx.txt
-histo
:输出堆中对象的统计信息,包括类、实例数量和合计容量。-histo:live,只统计存活对象-permstat
:以ClassLoader为统计口径输出永久代的内存状态信息(Linux)-finalizerinfo
:显示在F-queue
中等待Finalizer线程执行finalize方法的休息(Linux)-F
:当虚拟机进程堆-dump选项没有任何相应时,可使用此项强制执行生成dump文件(Linux)-J <flag>
:传递参数给jmap启动的jvm
5 jhat JDK自带堆分析工具
Sun JDK提供的jhat命令与jmap命令搭配使用,用于分析jmap生成的heap dump文件(堆转储快照)。jhat内置了一个微型的HTTP/HTML服务器, 生成dump文件的分析结果后,用户可以在浏览器中查看分析结果(分析虚拟机转储快照信息)。
使用了ihat命令,就启动了一个http服务,端口是7000,即http://localhost:7000/就可以在浏览器里分析。
说明:官方建议用VisualVM代替,jhat命令在JDK9、JDK10中已经被删除
# jhat 文件地址
jhat xxxxx.hprof
6 jstack 打印JVM中线程快照
生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪)。 线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。 生成线程快照的作用:可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。这些都是导致线程长时间停顿的常见原因。当线程出现停顿时,就可以用jstack显示各个线程调用的堆情况。
6.1 线程状态
死锁代码
public class JstackDeadLockTest { public static void main(String[] args) throws IOException { Object obj1 = new Object(); Object obj2 = new Object(); new Thread(() -> { synchronized (obj1) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj2){} } }, "A-Thread").start(); new Thread(() -> { synchronized (obj2) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (obj1){} } }, "B-Thread").start(); System.in.read(); } }
jstack查看,jstack PID
执行中,Runnable
暂停,Suspended
对象等待中,0bject.wait() 或 TIMED WAITING
停止,Parked
6.2 参数
-F
:当正常输出请求不被响应时,强制输出线程堆栈-l
:除堆栈外,显示关于锁的附加信息-m
:如果调用到本地方法的话,可以显示C/C++的堆栈
7 jcmd 多功能命令行
它是一个多功能的工具,可以用来实现前面除了jstat之外所有命令的功能。用它来导。比如:出堆、内存使用、查看Java进程、导出线程信息、执行GC、JVM运行时间等
jcmd拥有jmap的大部分功能,并且在Oracle的官方网站上也推荐使用jcmd命令代jmap命令
- jcmd -l:列出所有的JVM进程
- jcmd pid help:针对指定的进程,列出支持的所有命令
- jcmd pid 具体指令:
二、分析工具
1 JDK 自带的工具
- 8.2 jconsole
- 8.3 JMC