JVM性能调优监控工具专题一:JVM自带性能调优工具
Posted Elvis_lfc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM性能调优监控工具专题一:JVM自带性能调优工具相关的知识,希望对你有一定的参考价值。
前提概要:
JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps、jstack、jmap、jhat、jstat、hprof等小巧的工具,每一种工具都有其自身的特点,用户可以根据你需要检测的应用或者程序片段的状况,适当的选择相应的工具进行检测。接下来的两个专题分别会讲VisualVM的具体应用。
现实企业级Java开发中,有时候我们会碰到下面这些问题:
OutOfMemoryError,内存不足
内存泄露
线程死锁
锁争用(Lock Contention)
Java进程消耗CPU过高
......
这些问题在日常开发中可能被很多人忽视(比如有的人遇到上面的问题只是重启服务器或者调大内存,而不会深究问题根源),但能够理解并解决这些问题是Java程序员进阶的必备要求。
基本工具命令
jps
实际中这是最常用的命令,下面要介绍的小工具更多的都是先要使用jps查看出当前有哪些Java进程,获取该Java进程的id后再对该进程进行处理。
jps主要用来输出JVM中运行的进程状态信息。语法格式如下:
[plain] view plain copy
- jps [options] [hostid]
如果不指定hostid就默认为当前主机或服务器。
命令行参数选项说明如下:
[plain] view plain copy- -q 不输出类名、Jar名和传入main方法的参数
- -m 输出传入main方法的参数
- -l 输出main类或Jar的全限名
- -v 输出传入JVM的参数
比如
1、我现在有一个WordCountTopo的Strom程序正在本机运行。
2、使用java -jar deadlock.jar & 启动一个线程死锁的程序
[plain] view plain copy- wangsheng@WANGSHENG-PC /E
- $ jps -ml
- 14200 deadlock.jar
- 13952 com.wsheng.storm.topology.WordCountTopo D://input/ 3
- 13248 sun.tools.jps.Jps -ml
- 9728
jstack
jstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:
[plain] view plain copy- jstack [option] pid
- jstack [option] executable core
- jstack [option] [server-id@]remote-hostname-or-ip
命令行参数选项说明如下 [plain] view plain copy
- -l long listings,会打印出额外的锁信息,在发生死锁时可以用 jstack -l pid 来观察锁持有情况
- -m mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)
jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。
下面我们来一个实例:
找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。
先找出Java进程ID,服务器上的Java应用名称为wordcount.jar:
[plain] view plain copy- [root@storm-master home]# ps -ef | grep wordcount | grep -v grep
- root 2860 2547 13 02:09 pts/0 00:02:03 java -jar wordcount.jar /home/input 3
得到进程ID为2860(也可以使用其它方式得到java的进程号),
找出该进程内最耗费CPU的线程,可以使用如下3个命令,这里我们使用第3个命令得出如下结果:
[plain] view plain copy- 1)ps -Lfp pid : 即 ps -Lfp 2860
- 2)ps -mp pid -o THREAD, tid, time :即 ps -mp 2860 -o THREAD,tid,time
- 3)top -Hp pid: 即 top -Hp 2860
TIME列就是各个Java线程耗费的CPU时间,显然CPU时间最长的是ID为2968的线程,用
[plain] view plain copy- printf "%x\\n" 2968
得到2968的十六进制值为b98,下面会用到。
终于轮到jstack上场了,它用来输出进程2860的堆栈信息,然后根据线程ID的十六进制值grep,如下:
[plain] view plain copy- [root@storm-master home]# jstack 2860 | grep b98
- "SessionTracker" prio=10 tid=0x00007f55a44e4800 nid=0xb53 in Object.wait() [0x00007f558e06c000
可以看到CPU消耗在SessionTracker这个类的Object.wait(),于是就能很容易的定位到相关的代码了。
jmap和 jhat
jmap用来查看堆内存使用状况,一般结合jhat使用。
jmap语法格式如下:
[plain] view plain copy- jmap [option] pid
- jmap [option] executable core
- jmap [option] [server-id@]remote-hostname-or-ip
如果运行在64位JVM上,由于linux操作系统的不同,可能需要指定-J-d64命令选项参数。
打印进程的类加载器和类加载器加载的持久代对象信息: jmap -permstat pid
个人感觉这个不是太有用
输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息,如图:
查看进程堆内存使用情况:包括使用的GC算法、堆配置参数和各代中堆内存使用:jmap -heap pid
比如下面的例子
[plain] view plain copy- [root@storm-master home]# jmap -heap 2860
- Attaching to process ID 2860, please wait...
- Debugger attached successfully.
- Server compiler detected.
- JVM version is 20.45-b01
- using thread-local object allocation.
- Mark Sweep Compact GC
- Heap Configuration:
- MinHeapFreeRatio = 40
- MaxHeapFreeRatio = 70
- MaxHeapSize = 257949696 (246.0MB)
- NewSize = 1310720 (1.25MB)
- MaxNewSize = 17592186044415 MB
- OldSize = 5439488 (5.1875MB)
- NewRatio = 2
- SurvivorRatio = 8
- PermSize = 21757952 (20.75MB)
- MaxPermSize = 85983232 (82.0MB)
- Heap Usage:
- New Generation (Eden + 1 Survivor Space):
- capacity = 12189696 (11.625MB)
- used = 6769392 (6.4557952880859375MB)
- free = 5420304 (5.1692047119140625MB)
- 55.53372290826613% used
- Eden Space:
- capacity = 10878976 (10.375MB)
- used = 6585608 (6.280525207519531MB)
- free = 4293368 (4.094474792480469MB)
- 60.53518272307982% used
- From Space:
- capacity = 1310720 (1.25MB)
- used = 183784 (0.17527008056640625MB)
- free = 1126936 (1.0747299194335938MB)
- 14.0216064453125% used
- To Space:
- capacity = 1310720 (1.25MB)
- used = 0 (0.0MB)
- free = 1310720 (1.25MB)
- 0.0% used
- tenured generation:
- capacity = 26619904 (25.38671875MB)
- used = 15785896 (15.054603576660156MB)
- free = 10834008 (10.332115173339844MB)
- 59.30110040967841% used
- Perm Generation:
- capacity = 33554432 (32.0MB)
- used = 33323352 (31.779624938964844MB)
- free = 231080 (0.22037506103515625MB)
- 99.31132793426514% used
查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象:jmap -histo[:live] pid
[plain] view plain copy
- [root@storm-master Desktop]# jmap -histo 2860
- num #instances #bytes class name
- ----------------------------------------------
- 1: 13917 11432488 [B
- 2: 6117 6181448 <instanceKlassKlass>
- 3: 39520 6004504 <constMethodKlass>
- 4: 6117 5517072 <constantPoolKlass>
- 5: 39520 5383280 <methodKlass>
- 6: 5148 3150944 <constantPoolCacheKlass>
- 7: 29954 2810640 [C
- 8: 50179 2469272 <symbolKlass>
- 9: 42122 1791704 [Ljava.lang.Object;
- 10: 1804 961464 <methodDataKlass>
- 11: 11747 941200 [Ljava.util.HashMap$Entry;
- 12: 28786 921152 java.lang.String
- jvm 性能调优工具之 jstat 命令详解