在java程序运行时,我们不仅仅需要关注基本的功能实现,还需要关注性能相关的问题,除了软件额度相关功能以外,性能可以说是衡量软件优劣最重要的指标之一。之前我总结了一些在linux系统下提供给我们的诊断程序运行性能的工具,感兴趣的同学可以去看一下:
https://juejin.im/post/5d71f1e3e51d453c135c5b41
下面主要说的就是jdk自带提供给我们的用于性能监控和进行诊断的一些工具,掌握好这些工具的使用,可以让我们更好的去在实际开发过程中改善系统的性能问题,以及出现复杂的内存异常时,能更好的进行诊断并解决.
1.查看java进程--jps命令
jps命令类似于linux下的ps,但它只用于列出java的进程,直接运行的话,不加任何参数,可以列出java程序程序进程id以及Main函数的名称。
如下示例:
jps -m -l -p
其中有一些参数的含义,例如: -m用于输出传输给java进程的参数。
-v 可以显示传递给java虚拟机的参数
2、查看虚拟机运行时命令- jstat(常用)
这个命令可以观察java应用程序运行时相关信息的工具。功能非常强大,可以利用它查看堆栈信息。
语法如下:
选项option可以由以下值构成:
-t参数可以在输出信息加上一个timeestamp列,显示程序运行的时候。
-h参数可以在周期性数据输出时,输出多少行数据后,跟着输出一个表头的信息。
interval参数用于指定输出统计数据的周期,单位为毫秒。
count用于指定一个输出多少次数据。
下面看代码例子:
例1
jstat -class -t -h1 9876 1000 2
在-class的输出中,以上表示进程9876的classLoad的相关信息,每秒统计一次信息,一共输出两次。每打印一行,输出头部信息。
load表示载入类的数量,Byte表示载入类的大小,Unload表示卸载类的数量,第二个Byte表示卸载类的大小。Time表示加载和卸载类上所花的时间。
例2: 查看jit编译信息
以上结果:
Compiled表示编译任务的执行的次数,Failed表示编译失败的次数,Invalid表示编译不可用的次数,Time表示编译的总耗时,FailedType表示最后一次编译失败的类型,FailedMethod表示最后一次编译失败的类名和方法名。
例三:查看GC堆的信息。
jstat -gc 9876
MC:方法区大小
MU:方法区使用大小
CCSC:压缩类空间大小
CCSU:压缩类空间使用大小
还可以显示各个年代的信息:
jstat -gccapacity 9876
NGCMN:新生代最小容量
NGCMX:新生代最大容量
NGC:当前新生代容量
S0C:第一个幸存区大小
S1C:第二个幸存区的大小
EC:伊甸园区的大小
OGCMN:老年代最小容量
OGCMX:老年代最大容量
OGC:当前老年代大小
OC:当前老年代大小
MCMN:最小元数据容量
MCMX:最大元数据容量
MC:当前元数据空间大小
CCSMN:最小压缩类空间大小
CCSMX:最大压缩类空间大小
CCSC:当前压缩类空间大小
YGC:年轻代gc次数
FGC:老年代GC次数
还可以查看最近一次GC的原因以及当前gc的原因:
jstat -gccause 9876
LGGC: 上次GC的原因。
GCC: 当前GC的原因。
以下整理一些参数,结合以上的例子,可以看不同年代的区的信息
-gcnew : 新生代
-gcnewcapacity 详细输出新生代的各个区大小信息。
-gcold 展示老年代的gc情况
-gcpacacity 永久区的使用情况
-gcutil 展示gc回收的相关信息
查看虚拟机参数 jinfo(常用)
该命令可以用来查看正在运行的java虚拟机的扩展参数,甚至支持在运行时修改扩展参数。
语法如下
jinfo <option> <pid>
其中option可以为如下信息:
-flag 打印指定虚拟的参数值
-flag[+|-]< name >: 指定java虚拟机参数的布尔值
-flag< name > 指定java虚拟机参数的值
很多情况下,java应用程序不会指定所有的虚拟机的参数值,此时,开发人员可以通过该命令找到虚拟机参数的当前值。
例如:
jinfo -flag PrintDeatils 9876 -XX:-PrintDetails
jinfo不仅可以查看运行时虚拟机某个参数的值也可以运行时修改部分参数的值,并立即生效。
4、导出堆到文件----jmap(常用)
jmap命令可以生成java程序的堆dump文件,也可以查看堆内对象实例的统计信息、查兰classLoader的信息和finalizer队列。
1.生成java程序的堆dump文件,得到当前堆快照
jmap -dump:format=b,file=c:\heap.hprof
在生成了堆快照后,可以通过多种工具分析该堆文件。
2.查看classLoader的信息
jmap -clstats [pid]
3.生成java程序的对象统计信息,并输出到s.txt文件
jmap -histo [pid] >c:\s.txt
结果如下:
5.jdk自带的堆分析工具---jhat
可以用于分析java应用程序的堆快照内容
jhat 堆文件地址
6.查看线程的堆栈---jstack(常用)
用于导出java应用程序的线程堆栈
jstack -l <pid>
-l 用于打印锁的附加信息
运行一个死锁的线程:
从信息的最后一行,我们很容易得到死锁的发生,同时找到了死锁的两个线程,以及死锁线程的持有对象和等待对象。
7.远程主机信息收集---jstatd命令
jstatd 是一个RMI服务端程序,作用相当于代理服务器,建立本地计算机与远程监控工具的通信。jstatd服务器会将本机的java应用程序传递到远程计算机
直接打开可能会抛出拒绝访问的异常,因此需要使用java的安全策略,为其分配权限。
下面会为jstatd分配最大的权限,将其保存在jstatd.all.policy文件中。
然后使用如下命令再次开启jstatd服务器:
就可以开启成功了。