JVM性能调优监控工具

JVM性能调优监控工具

JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps、jstack、jmap、jhat、jstat、hprof等小巧的工具.
在Java应用中,我们会经常碰到下面这些问题:
OutOfMemoryError,内存不足
内存泄露
线程死锁
锁争用(Lock Contention)
Java进程消耗CPU过高
......

本文将对一些常用的JVM性能调优监控工具进行介绍,对以后java应用出现上述问题后,可以进行优化和找到问题的根源,而不是简单粗暴的重启应用和添加内存了.

1. jps(Java Virtual Machine Process Status Tool)
jps主要用来输出JVM中运行的进程状态信息。

特殊说明
jps仅查找当前用户的Java进程,而不是当前系统中的所有进程。
比较常用的参数如下:

-q  只显示pid,不显示class名称,jar文件名和传递给main方法的参数
-m  输出传入main方法的参数
-l  输出应用程序main class的完整package名 或者 应用程序的jar文件完整路径名
-v  输出传入JVM的参数

实例:

[root@localhost ~]# jps
23991 Jps
23789 BossMain
23651 Resin
[root@localhost ~]# jps -q
28680
23789
23651
[root@localhost ~]# jps -m
28715 Jps -m
23789 BossMain
23651 Resin -socketwait 32768 -stdout /data/aoxj/resin/log/stdout.log -stderr /data/aoxj/resin/log/stderr.log
[root@localhost ~]# jps -l
28729 sun.tools.jps.Jps
23789 com.asiainfo.aimc.bossbi.BossMain
23651 com.caucho.server.resin.Resin
[root@localhost ~]# jps -v
23789 BossMain
28802 Jps -Denv.class.path=/data/aoxj/bossbi/twsecurity/java/trustwork140.jar:/data/aoxj/bossbi/twsecurity/java/:/data/aoxj/bossbi/twsecurity/java
k15/lib/tools.jar -Dapplication.home=/data/aoxj/jdk15 -Xms8m
23651 Resin -Xss1m -Dresin.home=/data/aoxj/resin -Dserver.root=/data/aoxj/resin -Djava.util.logging.manager=com.caucho.log.LogManagerImpl -Djavax
当然也可以组合使用,如:
jps -ml 或者jps -mlv

2.jstack

jstack主要用来查看某个Java进程内的线程堆栈信息,可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多.
下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep.

1.用ps -ef | grep tomcat_8080 查出tomcat运行的进程id  
#进程id:78824

2.用top -Hp pid 查询进程下所有线程的运行情况(shift+p 按cpu排序,shift+m 按内存排序)
#top -Hp 78824

3.找到cpu最高的pid,用printf '%x\n' pid 转换为16进制
#最高的pid:78824
[root@v01-apppre-task01 ~]# printf '%x\n' 78824
133e8

4.用jstack 进程id | grep 16进制线程id 找到线程信息
#jstack 78824 |grep 133e8

每隔5秒钟收集一次堆栈信息,共收集10次.

$ for i in `seq 1 10`; do echo $i; /usr/bin/jstack -l pid >> dump.txt; sleep 5; done
如果没有jstack命令,执行如下命令安装:
# yum install java-11-openjdk-devel.x86_64 -y

3.jmap(Memory Map)和jhat(Java Heap Analysis Tool)

 jmap是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。打印出某个java进程(使用pid)内存内的,所有‘对象’的情况,一般结合jhat使用.

使用jmap -heap pid查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况,如下:

#jmap -heap 2845

使用jmap -histo[:live] pid查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象,如下:

#jmap -histo:live 2845 | more

用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。jmap进行dump命令格式如下:

#jmap -dump:live,format=b,file=/tmp/dumpfilename.bin 2845

dump出来的文件可以用MAT、VisualVM等工具查看,这里用jhat查看:

#jhat -port 9998 /tmp/dumpfilename.bin

注意如果Dump文件太大,可能需要加上-J-Xmx512m这种参数指定最大堆内存,即jhat -J-Xmx512m -port 9998 /tmp/dumpfilename.bin.然后就可以在浏览器中输入http://localhost:9998查看了.

也可以使用java自带的VisualVm工具进行堆栈信息的分析.

 

 ###################################################################################

记录一次JAVA进程cpu使用率高排查方法

1、jps  #查看正在运行的java进程

8722 jboss-modules.jar

2、top     #确定使用cpu最高的java进程为 8722 

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
8722 root      20   0 50.6g  15g  25m S 154.4 12.5 326:54.15 java

3、通过进程获取cpu使用率最高的线程id,两种方法可以获取线程id

方法一:top -Hp 进程号

# top -Hp 8722 

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                          
8968 root      20   0 50.6g  15g  25m S 16.0 12.5   1:19.83 java                                                                                                                              
8858 root      20   0 50.6g  15g  25m S  1.6 12.5   0:55.08 java                                                                                                                              

可以看到cpu使用率最高的线程id是8968

方法二:使用ps -mp 通过排序方式获取java 线程号.

# ps -mp 8722 -o THREAD,tid,time | sort -rn |more

USER     %CPU PRI SCNT WCHAN  USER SYSTEM   TID     TIME
root      1.4  19    - ep_pol    -      -  8968 00:03:41
root      133   -    - -         -      -     - 05:51:12

4、可以看到cpu使用最高的线程是8968,用printf “%x\n” tid 转换为16进制.

# printf "%x\n" 8968
2308
#

5、用jstack pid | grep 16进制线程id 找到线程信息。

# jstack 8722 |grep 2308 

"default task-37" #234 prio=5 os_prio=0 tid=0x00007f1ca8003800 nid=0x2308 waiting on condition [0x00007f1e2199b000]

或者执行:# jstack 8722 |grep 2308 -A 30 打印上下多行信息.

 

参考文档:https://blog.csdn.net/u011250186/article/details/99676292

 

posted @ 2017-12-07 13:50  梦徒  阅读(474)  评论(0编辑  收藏  举报