常用工具介绍:jps jinfo jmap jstack jstat
jps:进程状态信息
jinfo:参数信息
常用命令:
jinfo pid
jmap:查看内存
常用命令:
jmap -dump:[live,]format=b,file=<filename>:输出heap信息到文件,live表示只输出活的对象到文件。可以用jhat查看dump出的内存信息。
jmap -finalizerinfo:打印正等待回收的对象信息
jmap -heap:打印heap配置情况和使用情况
jmap -histo:打印class及其对象数和对象占用内存情况
jstack:查看线程
常用命令:
jstack pid:打印线程堆栈信息
jstat:性能分析
常用命令:
jstat -class:类加载统计
jstat -compile:编译统计
jstat -gc:垃圾回收统计
jstat -gccapacity:堆内存统计
jstat -gcnew:新生代垃圾回收统计
jstat -gcnewcapacity:新生代内存统计
jstat -gcold:老年代垃圾回收统计
jstat -gcoldcapacity:老年代内存统计
jstat -gcmetacapacity:元数据空间内存统计
jstat -gcutil:总体垃圾回收统计
使用方法:
用jstat打印gc整体情况,从而分析是内存(堆)问题还是线程(栈)问题,如果是内存问题用jmap进行具体分析,如果是线程问题用jstack进行具体分析;
无论是jstat、jmap、jstack,如果只是孤立的看某一时刻的gc信息是看不出问题的,必须要结合系统正常时和系统异常时gc信息对比来看才能看出问题。
总体思路:
一般来说,jvm问题要么是内存问题,要么是线程问题,所以第一步先确定是内存问题还是线程问题。
基本思路:
确定是内存问题还是线程问题;
基本方法(适用于所有分析工具和命令):
对比系统正常时和系统异常时异常参数在空间上和时间上的变化:
空间上:系统异常时和系统正常时该参数的变化;
时间上:系统异常时该参数的变化情况(一直异常还是交替异常);
一般套路:
1.jps打印出系统进程;
2.jstat -gcutil打印gc信息,关注异常参数在空间上和时间上的变化;
3.jmap -histo打印class及其对象数和对象占用内存,重点关注排名靠前的class;
4.jstack打印线程状态:
死锁, Deadlock(重点关注)
执行中,Runnable
等待资源, Waiting on condition(重点关注):比如等待网络读写
等待获取监视器, Waiting on monitor entry(重点关注):就是等待获取锁
暂停,Suspended
对象等待中,Object.wait() 或 TIMED_WAITING:synchronized内部调用wait方法暂时放弃锁
阻塞, Blocked(重点关注)
停止,Parked
【欢迎关注我的公众号】