虚拟机监控与处理工具

jps

显示系统内所有虚拟机进程。

选项

作用

-q

只输出LVMID,省略主类的名称

-m

输出虚拟机进程启动时传递给主类main()函数的参数

-l

输出主类的全名,如果进程执行的是jar包,输出jar路径

-v

输出虚拟机进程启动时jvm参数

[root ~]$ jps -l
87799 org.apache.catalina.startup.Bootstrap
319117 org.apache.catalina.startup.Bootstrap
182013 com.creditease.mscp.boot.MSCPBoot
241863 org.apache.catalina.startup.Bootstrap
262825 org.apache.catalina.startup.Bootstrap
82480 org.apache.catalina.startup.Bootstrap
261415 sun.tools.jps.Jps

jstat

用于收集虚拟机各方面的运行数据。

选项

作用

-class

监视类的装载、卸载数量以及类的装载总空间和耗费时间等

-gc

监视Java堆,包含eden、2个survivor区、old区和永久带区域的容量、已用空间、GC时间合计等信息

-gccapcity

监视内容与-gc相同,但输出主要关注Java区域用到的最大和最小空间

-gcutil

监视内容与-gc相同,但输出主要关注已使用空间占总空间的百分比

-gccause

与-gcutil输出信息相同,额外输出导致上次GC产生的原因

-gcnew

监控新生代的GC情况

-gcnewcapacity

与-gcnew监控信息相同,输出主要关注使用到的最大和最小空间

-gcold

监控老生代的GC情况

-gcoldcapacity

与-gcold监控信息相同,输出主要关注使用到的最大和最小空间

-gcpermcapacity

输出永久带用到的最大和最小空间

-compiler

输出JIT编译器编译过的方法、耗时信息

-printcompilation

输出已经被JIT编译的方法

[weblogic@vm-10-112-180-180 ~]$ jstat -gc 87799
 S0C    S1C    S0U    S1U      EC       EU        OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT   
13056.0 13056.0 301.9   0.0   104960.0 15747.8  3014656.0   791584.0  131072.0 83501.8   2786   23.422   0      0.000   23.422

S0C

当前survivor space 0 的总容量 (KB)

S1C

当前survivor space 1 的总容量 (KB)

S0U

当前survivor space 0 已使用的容量 (KB)

S1U

当前survivor space 1 已使用的容量 (KB)

EC

当前 eden space 总容量 (KB)

EU

当前eden space已经使用的容量 (KB)

OC

当前 old space 总容量 (KB)

OU

当前old space 已使用容量(KB)

PC

当前 permanent space 总容量(KB)

PU

当前 permanent space 已使用容量 (KB)

YGC

从应用启动时到现在,年轻代young generation 发生GC Events的总次数

YGCT

从应用启动时到现在, 年轻代Young generation 垃圾回收的总耗时

FGC

从应用启动时到现在, full GC事件总次数

FGCT

从应用启动时到现在, Full sc总耗时

GCT

从应用启动时到现在, 垃圾回收总时间. GCT=YGCT+FGCT

jinfo

显示虚拟机配置信息。实时的查看和调整JVM的各项参数。可以使用-flag [+/-]name或者-flag name=value修改一部分运行期可写的虚拟机参数。

输出gc日志
D:\>jinfo -flag +PrintGCDetails 4192

D:\>jinfo -flag +PrintGC 4192

jmap

生成虚拟机的内存转储快照(heapdump文件)

选项

作用

-dump

生产Java堆转储快照。格式为:-dump[live, ]format=b, file=<filename>。其中live子参数说明是否只dump存活的对象。

-finalizerinfo

显示在F-Queue中等待finalizer线程执行finalize方法的对象。只在Linux/Solaris平台下有效。

-heap

显示Java堆详细信息,如使用哪种回收器、参数配置、分代情况等。只在Linux/Solaris平台下有效。

-histo

显示堆中对象统计信息,包括类、实例数量、合计容量。

-permstat

以Classloader为统计口径显示永久代内存状态。只在Linux/Solaris平台下有效。

-F

当虚拟机进程对-dump选项没有响应时,可使用这个选项强制生产dump快照。只在Linux/Solaris平台下有效。

[root]$ jmap -dump:format=b,file=dump 182013
Dumping heap to /app/weblogic/pop-interface/logs/dump ...
Heap dump file created
[root]$ ll
total 133652
drwxr-xr-x 2 weblogic weblogic    40960 May 17 07:10 bak
-rw-rw-r-- 1 weblogic weblogic 42591197 May 17 15:56 catalina.2018-05-17.out
-rw------- 1 weblogic weblogic 92541638 May 17 15:57 dump
-rw-rw-r-- 1 weblogic weblogic  1638325 May 17 15:56 gc.log
-rw-rw-r-- 1 weblogic weblogic    23925 May 17 15:57 localhost_access_log.2018-05-17.log

jhat

分析heapdump文件,它会建立一个HTTP/HTML服务器,让用户可以在浏览器上查看分析结果。

D:\>jhat dump
...
Snapshot resolved.
Started HTTP server on port 7000

在浏览器中输入http://ip:7000,就可以查看分析结果。其中分析内存泄露问题主要会使用到其中的“Heap Histogram”功能。

jstack

显示虚拟机上的线程快照。线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的就定位线程出现长时间停顿的原因,如线程死锁、死循环等。

jstack pid

实践

查看GC log

2018-06-04T16:12:17.393+0800: 336894.721: [GC2018-06-04T16:12:17.393+0800: 336894.721: [ParNew: 1677824K->7137K(1887488K), 0.0167290 secs] 2058871K->388184K(3984640K), 0.0172050 secs] [Times: user=0.10 sys=0.00, real=0.02 secs] 
2018-06-04T16:12:39.083+0800: 336916.411: [Full GC2018-06-04T16:12:39.083+0800: 336916.411: [CMS: 381047K->380283K(2097152K), 1.3115720 secs] 481767K->380283K(3984640K), [CMS Perm : 171267K->171267K(285428K)], 1.3120450 secs] [Times: user=1.31 sys=0.00, real=1.31 secs] 

[ParNew(使用ParNew作为年轻代的垃圾回收期): 43296K(年轻代垃圾回收前的大小)->7006K(年轻代垃圾回收以后的大小)(47808K)(年轻代的总大小), 0.0136826 secs(回收时间)] 44992K(堆区垃圾回收前的大小)->8702K(堆区垃圾回收后的大小)(252608K)(堆区总大小), 0.0137904 secs(回收时间)] [Times: user=0.03(Young GC用户耗时) sys=0.00(Young GC系统耗时), real=0.02 secs(Young GC实际耗时)]  

高CPU占用

一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环或者是因为内存不足和导致频繁的full gc。

1、查看当前cpu的使用情况

top命令

2、查看当前pid下的线程情况

ps -mp pid -o THREAD,tid,time

3、将线程id转换为16进制

printf "%x\n" tid

4、打印线程快照信息

jstack pid |grep tid -A 30

高内存占用

1、查看当前内存的使用情况

命令top

2、查看当前内存活跃的对象和占用内存大小

jmap -histo:live pid

Last updated