jps
查看本地运行的java进程信息
参数
- -q:仅显示进程id
- -m:显示main方法的参数
- -l:显示main类或Jar的全限名
- -v:显示指定的JVM的参数
congqingquan@localhost Desktop % java Test param1 &
[1] 33965
congqingquan@localhost Desktop % jps
33965 Test
33967 Jps
congqingquan@localhost Desktop % jps -q
33968
33965
congqingquan@localhost Desktop % jps -m
33970 Jps -m
33965 Test param1
congqingquan@localhost Desktop % jps -l
33971 sun.tools.jps.Jps
33965 Test
congqingquan@localhost Desktop % jps -v
33973 Jps -Dapplication.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_211.jdk/Contents/Home -Xms8m
33965 Test
jstack
查看java进程中的线程的信息与方法调用栈
参数
-l:显示关于锁的信息
-m:显示调用本地方法时的本地方法栈堆
-F:当Java进程负载较高、无法响应时,强制dump线程快照
congqingquan@localhost Desktop % jstack -l 34236
34236: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding
输出内容解释
"C99" #10 prio=5 os_prio=31 tid=0x00007f9018178000 nid=0x5503 waiting on condition [0x000070000cf55000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at Test.lambda$main$0(Test.java:11)
at Test$$Lambda$1/303563356.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
第一行:线程基本信息
- C99为线程名
- tid:java线程的id
- nid:java线程映射的操作系统线程的线程id
- prio:java层面定义的线程的优先级
- os_prio:java线程映射的操作系统线程的优先级
第二行:线程的状态
第三行:线程的方法调用栈
jstat
查看堆内存的各个区域应用统计信息、GC信息,以及加载类的数量
这个命令用的不多,若需要分析堆内存的情况,一般通过jmap+分析工具的方式进行分析。可以用来观测GC是否频繁,例(1000为数据刷新间隔,单位毫秒):
congqingquan@localhost Desktop % jps
36129 Jps
34103 Launcher
34871 Test
congqingquan@localhost Desktop % jstat -gcutil 34871 1000
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 0.00 34.74 2.32 96.93 88.89 8 0.046 4 0.101 0.147
0.00 0.00 34.74 2.32 96.93 88.89 8 0.046 4 0.101 0.147
0.00 0.00 34.74 2.32 96.93 88.89 8 0.046 4 0.101 0.147
输出结果:
- S0:S0区堆内存占用比
- S1:S1区堆内存占用比
- E:Eden区堆内存占用比
- O:老年代堆内存占用比
- M:元空间占用比(对比默认元空间大小或JVM启动参数指定的元空间最大容量)
- CCS 压缩类占用比
- YGC:Young GC发生次数
- YGCT:Young GC的总体耗时
- FGC:Full GC发生次数
- FGCT:Full GC的总体耗时
- GCT:所有GC的总体耗时
jmap
查看堆内存的使用情况
最常用的参数:将堆内存使用情况dump到快照文件中(注意快照文件的后缀名)
jmap -dump:file=${fileName}.hprof ${pid}
部署服务程序时,为了分析可能会发生OOM,常会指定的两个JVM启动参数:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${filePath}
当发生OOM时,将堆内存使用情况dump到快照文件,并将快照文件写到指定路径处。若不指定HeapDumpPath JVM启动参数,生成的文件名默认为:java_pid${pid}.hprof。
可视化工具
jconsole:jps、jstack、jstat、jmap的输出结果,都可以在jconsle的可视化程序中查看。
线上环境一般是没有可视化界面的,所以jconsole的应用具有局限性。若一定想要在本地通过jconsole连接到远程java服务器,可以在远程服务器启动时添加以下的JVM启动参数来实现:
-Djava.rmi.server.hostname=xx.xx.xx.xx # 远程服务器ip
-Dcom.sun.management.jmxremote # 启用JMX远程调用
-Dcom.sun.management.jmxremote.port=8888 # JMX端口号
-Dcom.sun.management.jmxremote.ssl=false # 是否开启ssl
-Dcom.sun.management.jmxremote.authenticate=false # 是否开启身份认证
一般排查内存问题时,jconsole并不常用,因为涉及开启部署服务器的JMX端口的安全问题。因此,一般都是通过jmap dump堆内存的快照文件,通过不同的工具分析dump的快照文件,来进行内存问题的排查。如:
jvisualvm:jdk自带的分析工具。具有jconsole的功能,又支持通过导入dump的快照文件进行内存分析。
MAT(Eclipse Memory Analyzer):相比jvisualvm更加强大,具有更多的功能,分析能力强大,更方便我们进行内存问题排查。
除此之外,还有其他的排查工具,如阿里的Arthas。后面,我们使用MAT来排查分析模拟的OOM溢出。