jvm监控和诊断工具

大牛写的Java的OOM Killer:https://www.jianshu.com/p/4645254be259 强烈推荐

总的参考链接:https://cloud.tencent.com/developer/article/1370313

jps参考链接:https://blog.csdn.net/u013250071/article/details/80496623

jstat参考链接:https://blog.csdn.net/JacksonKing/article/details/91359363;https://www.cnblogs.com/lizhonghua34/p/7307139.html

jmap参考链接:https://blog.csdn.net/jiang_zf/article/details/79540234(写得非常好,推荐阅读,更好地理解jvm中堆和栈的作用);https://www.cnblogs.com/qq78292959/p/5141209.html

jinfo参考链接:https://blog.csdn.net/u012998254/article/details/81121942

jstack参考链接:https://www.cnblogs.com/taiguyiba/p/9470861.html

  • jps-Java Virtual Machine Process Status Tool

java提供的一个显示当前所有java进程pid的命令,我们可以通过它来查看我们到底启动了几个java进程(因为每一个java程序都会独占一个java虚拟机实例)。

而ps命令是用来显示当前系统的进程情况,有哪些进程以及进程id。

  • jstat-Java Virtual Machine statistics monitoring tool

主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。

 jstat工具特别强大,有众多的可选项,详细查看堆内各个部分的使用量,以及加载类的数量。使用时,需加上查看进程的进程id,和所选参数。参考格式如下:

-class (类加载器) 
-compiler (JIT) 
-gc (GC堆状态) 
-gccapacity (各区大小) 
-gccause (最近一次GC统计和原因) 
-gcnew (新区统计)
-gcnewcapacity (新区大小)
-gcold (老区统计)
-gcoldcapacity (老区大小)
-gcpermcapacity (永久区大小)
-gcutil (GC统计汇总)
-printcompilation (HotSpot编译统计)

比如:jstat –class pid: 显示加载class的数量,及所占空间等信息;jstat -gc pid: 可以显示gc的信息,查看gc的次数,及时间。pid可以用jps命令查看。

  • jmap-Java Memory Map

用于打印指定Java进程(或核心文件、远程调试服务器)的共享对象内存映射或堆内存细节。

jmap命令可以获得运行中的jvm的堆的快照,从而可以离线分析堆,以检查内存泄漏检查一些严重影响性能的大对象的创建,检查系统中什么对象最多,各种对象所占内存的大小等等。可以使用jmap生成Heap Dump,再配合MAT(内存分析工具)。一般,在内存不足、GC异常等情况下,我们就会怀疑有内存泄漏,这个时候我们就可以制作堆Dump来查看具体情况。

比如:jmap -heap pid 展示pid的整体堆信息;jmap -histo:live pid展示存活的class内存情况,可以在命令后加上| more,一页一页地看,当然也可以直接输出到文件中,然后查看jmap -histo:live pid>a.log;jmap -dump:live,format=b,file=a.log pid这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用。生产慎用!

可以利用该命令来分析内存泄漏OOM,做法如下图:

  •  jinfo-Java Configuration Info

用来查看正在运行的Java应用程序的扩展参数,甚至支持在运行时,修改部分参数。

比如:jinfo -flag pid

  • jstack

用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

系统性能瓶颈定位

一、高CPU的问题分析:

  1. 资源消耗分析
  1. Top命令查看系统
  2. 查看使用最多的应用进程 pid

系统性能瓶颈定位_html_2893c4ff1b099d11.png

  1. Top –H –p pid查看对应进程下资源消耗最多的线程,持续观察一段时间,找到持续耗cpu最多的线程(top –H –p 27555)

系统性能瓶颈定位_html_faf4d84eb82e0dd9.png

  1. 将线程号转换为16进制(printf "%x " TID ----TID为线程ID)
  2. 生成堆栈信息jstack -l pid >> prod.jstack.IP(pid为进程ID)
  3. 在堆栈信息中查找,less prod.jstack.IP,查找上面转换为16进制的线程,到底资源消耗在做什么

系统性能瓶颈定位_html_1b0ded1c21b0b8f2.png

确认大部分的资源在等待activeMQ的应答

 二、内存分析

内存分两种,系统级别的剩余内存和各进程的剩余内存

1、系统级别的剩余内存可以通过命令:free来查看

系统性能瓶颈定位_html_f37218c093147460.png

剩余内存是:free+buffers+cached

2、进程的剩余内存

每个进程会分配一部分内存,像jboss应用的服务,如poseidon,在/app/poseidon/jboss/bin/standalone.conf文件中有JAVA_OPTS="-Xms512m -Xmx2g ......."的配置,说明这个java进程分配了最小512M,最大2G内存。

那这个进程的内存使用情况是怎么样,可以查看这个进程的状态,命令:cat /proc/PID/status(PID是进程号),如下:

系统性能瓶颈定位_html_1cb95e0a6cc774ef.png

上图涉及的内容比较多,主要关系到内存的部分是:

VmSize: 1342408 kB /*进程虚拟地址空间的大小*/

VmLck: 0 kB /*进程已经锁住的物理内存的大小.锁住的物理内存不能交换到硬盘*/
 VmHWM: 18020 kB /*文件内存映射和匿名内存映射的大小*/
 VmRSS: 18020 kB /*应用程序正在使用的物理内存的大小,就是用ps命令的参数rss的值 (rss)*/
 VmData: 12240 kB /*程序数据段的大小(所占虚拟内存的大小),存放初始化了的数据*/
 VmStk: 84 kB /*进程在用户态的栈的大小*/
 VmExe: 576 kB /*程序所拥有的可执行虚拟内存的大小,代码段,不包括任务使用的库 */
 VmLib: 21072 kB /*被映像到任务的虚拟内存空间的库的大小*/

这个命令中的其他信息也很有用,如:

Tgid: 9744 /*线程组号*/

Pid:23019 /*进程pid*/
 PPid: 1 /*父进程的pid*/
 TracerPid: 0 /*跟踪进程的pid*/

Threads:39 /*该进程的线程数 */

FDSize: 256 /*文件描述符的最大个数,file->fds*/
 

需要关心的值是VmSize和VmRSS,分配的物理内存和实际被使用的物理内存,如果VmRSS/VmSize,内存的使用率超过90%就需要注意,可能会出现内存不足或内存溢出等情况。

另外,补充说明下检查内存泄露的工具:Elipse Memory Analysis。如下:

工具有windows版,可以直接在网上下载

解压,运行MemoryAnalyzer.exe即可

步骤:

  1. 在测试完之后,等待一段时间后内存回收,或用JAVA自带的jstat工具GC回收,如:%JAVA_HOME%/bin/jstat -gcutil pid 1000 10;-----具体可查看jstat的帮助文档
  2. 运用Java自带的jmap工具,把内存信息保存,如下:%JAVA_HOME/bin/jmap -dump:format=b,file=jmap.hprof pid(18575);-----内存信息保存在jmap.hprof文件中
  3. 把服务器上的jmap.hprof拷贝到装有Eclipse MemoryAnalyzer的机器上;
  4. 打开MemoryAnalyzer,在界面上选择“Open Heap Dump”,选择步骤3中导出来的jmap.hprof文件;----如下图一
  5. 加载成功后按默认选项点“Finishd”,会出现图二中内存分析的图表,从图二中,分析出a标识区域有可能存在内存泄露或其他问题,可以再查看Details详细分析;

补充:以上只是简单的使用,至于jstat、jmap工具的使用,以及内存的分析,还有很多需要学习的地方,请大家一起。

系统性能瓶颈定位_html_ed3c59694a20c348.gif

图一

系统性能瓶颈定位_html_59b7240c57500981.png

图二

三、IO读写

Iostat命令直接查看:

系统性能瓶颈定位_html_cab0fa7aef3e20d3.png

rMB/s:每秒从设备(drive expressed)读取的数据量;

wMB/s:每秒向设备(drive expressed)写入的数据量;

具体,可以见下面链接:https://www.cnblogs.com/mululu/p/5959362.html

四、网络流量

Sar 命令

原文地址:https://www.cnblogs.com/fxl-njfu/p/11356945.html