深刻理解JVM(七)——性能监控工具

前言html

  工欲善其事必先利其器,性能优化和故障排查在咱们大都数人眼里是件比较棘手的事情,一是须要具有必定的原理知识做为基础,二是须要掌握排查问题和解决问题的流程、方法。本文就将介绍利用性能监控工具,帮助开发者更快更准的找到问题产生的根源。本文分为三部分,第一部分将介绍在Linux环境下的经常使用监控工具,第二部分介绍Windows环境下的监控工具,第三部分将经过一个案例,介绍利用这些监控工具一步一步找出java应用程序的问题。java

Linux环境下的监控工具sql

  须要先声明的是,下面介绍的部分工具其实在Liunx环境、Windows环境下均可以使用,只不过在不一样的环境下使用什么工具更合适。shell

  下面咱们想象这么一个场景:有一天运维人员看到生产环境下的服务器负载升高、CPU飙升,内存占用增大,请问接下来他该怎么办?可能有人会说,那就找到负载升高、CPU飙升。。的缘由啊,若是是应用程序形成的就把它kill掉。若是采用这种方法,问题可能会短期解决,但带来的问题是应用在一段时间不可用,而且咱们没有找到问题发生的根源,下次重启后,问题依然会产生。那么若是出现相似的问题,严格的排查流程是怎样的呢?在回答这个问题以前,咱们先了解一下Linux上经常使用的几个监控工具:windows

uptimecentos

[root@centos7_template ~]# uptime 10:31:42 up 4 days, 1:01, 1 user,load average: 0.02, 0.02, 0.05
10:31:42    //当前系统时间
up 4 days, 1:01 //持续运行时间,时间越大,说明你的机器越稳定。 
1 user  //用户链接数,是总链接数而不是用户数 
load average: 0.02, 0.02, 0.05  //系统平均负载,统计最近1,5,15分钟的系统平均负载

该命令将显示目前服务器持续运行的时间,以及负载状况。性能优化

经过这个命令,能够最简便的看出系统当前基本状态信息,这里面最有用是负载指标,若是你还想查看当前系统的CPU/内存以及相关的进程状态,可使用TOP命令。服务器

TOP运维

70NN3YT1%9[V1M5EU4{FPGQ

经过TOP命令能够详细看出当前系统的CPU、内存、负载以及各进程状态(PID、进程占用CPU、内存、用户)等。从上面的结果看出该系统上安装了MySQL、java,能够看到他们各自的进程ID,假如这时Java进程占用较高的CPU和内存,那么你就要留心了,若是程序中没有计算量特别大、占用内存特别多的代码,可能你的java程序出现了未知的问题,能够根据进程ID作进一步的跟踪。除了经过TOP命令找到进程信息之外,还能够经过jdk自带的工具JPS直接找到java程序的进程号。nosql

JPS

image

能够看到jps命令直接罗列出了当前系统中存在的java进程,这里第一个是jps命令本身的java进程,而另一个是我启动的nosql监控工具进程。经过这种方法查询到java程序的进程ID后,能够进一步经过:

top -p 3618 // 这里的3618就是上面查询到的java程序的进程ID

image

经过此方法能够准确的查看指定java进程的CPU/内存使用状况。

除此以外,vmstat命令也能够查看系统CPU/内存、swap、io等状况:

VIBLT41${5HGEYJ}QZ)~T`T

上面的命令每隔1秒采样一次,一共采样四次。CPU占用率很高,上下文切换频繁,说明系统有线程正在频繁切换,这多是你的程序开启了大量的线程存在资源竞争的状况。另外swap也是值得关注的指标,若是swpd太高则可能系统能使用的物理内存不足,不得不使用交换区内存,还有一个例外就是某些程序优先使用swap,致使swap飙升,而物理内存还有不少空余,这些状况是须要注意的。

查看系统指标,还有一个第三方工具:pidstat,这个工具仍是很好用的,须要先安装:

yum install sysstat

image

该命令监控进程id为3618的CPU状态,每隔1秒采样一次,一共采样四次。“%CPU”表示CPU使用状况,“CPU”则表示正在使用哪一个核的CPU,这里为0表示正在使用第一个核。若是还要显示线程ID,则可使用:

pidstat -p 3618 -u -t 1 4

若是要监控磁盘读写状况,这可使用:

image

pidstat还有其余的参数,能够经过pidstat --help获取,再次再也不赘述。

下面再介绍几个JDK自带有用的工具:jps、jstat、jmap、jstack

jps:上面咱们已经使用过了,他能够罗列出目前再服务器上运行的java程序及进程ID;

jstat:用于输出java程序内存使用状况,包括新生代、老年代、元数据区容量、垃圾回收状况。

image

上述命令输出进程ID为3618的内存使用状况(每2000毫秒输出一次,一共输出20次)

  • S0:幸存1区当前使用比例
  • S1:幸存2区当前使用比例
  • E:伊甸园区使用比例
  • O:老年代使用比例
  • M:元数据区使用比例
  • CCS:压缩使用比例
  • YGC:年轻代垃圾回收次数
  • FGC:老年代垃圾回收次数
  • FGCT:老年代垃圾回收消耗时间
  • GCT:垃圾回收消耗总时间

jmap:用于输出java程序中内存对象的状况,包括有哪些对象,对象的数量。

jmap -histo 3618

上述命令打印出进程ID为3618的内存状况。但咱们经常使用的方式是将指定进程的内存heap输出到外部文件,再由专门的heap分析工具进行分析,例如mat(Memory Analysis Tool),因此咱们经常使用的命令是:

jmap -dump:live,format=b,file=heap.hprof 3618

将heap.hprof传输出来到window电脑上使用mat工具分析:

{U[6FUIMFB%~8B~ZWC9C(RL

jstack:用户输出java程序线程栈的状况,经常使用于定位由于某些线程问题形成的故障或性能问题。

jstack 3618 > jstack.out

上述命令将进程ID为3618的栈信息输出到外部文件,便于传输到windows电脑上进行分析。

Windows环境下的监控工具

Windows环境下的监控工具也有不少,可是本文主要推荐jvisualvm.exe、MemoryAnalyzer.exe,有了他们其余工具几乎不须要了。

jvisualvm.exe在JDK安装目录下的bin目录下面,双击便可打开。

[(12G94WOFP`XLH1}BL[SD8

双击左侧你须要监控的java程序便可对它进行监控,这个工具包括对CPU、内存、线程、类都作了监控,功能很是强大,上文中介绍的全部功能,其余在这个工具上都已经有了。固然怎么用、如何分析它须要花时间去一点点积累。

MemoryAnalyzer.exe:上文咱们已经提到,经常使用于分析内存堆使用状况,也是很是强大的工具。详细使用方法,这里就再也不赘述,能够下载下来尝试一下。

上述介绍了基于Linux、Windows环境的监控工具,有了这些工具咱们就要利用他们作对应的事情,下面将经过一个简单的案例,说明如何使用他们。

案例分析

首先经过上述的介绍,咱们对故障排查流程应该有了一个印象,这里先梳理出来:

image

案例:

 一个java应用启动之后,使用人员发现应用不可用,针对该现象咱们作如下分析排查:

一、首先查看服务器上的应用状态。使用jps命令查询当前在运行中的java进程:

image

这里进程ID为6400的java应用就是咱们刚启用的,说明应用并无挂掉,还在运行中。

二、经过进程ID查询所占用的CPU、内存以及当前负载状况,top -p 6400。

 

 

image

从以上结果看出该应用并无引发系统负载太高,CPU、内存也没有出现异常状况。

三、经过上述结果咱们推测由于内存缘由引发的故障可性能较小,因此咱们优先排查线程栈,使用jstack命令,导出线程栈。

jstack 6400 > stack.out

咱们将该文件传输出来便于查看。

D{1SED$N[6E`YTTO9CZH%SQ

查看线程栈能够看出,主线程处于运行状态,而子线程ThreadA、ThreadB、ThreadC、ThreadD一边在等待一个锁,同时又持有另一个锁,其实看到这里咱们基本推断该应用程序存在死锁,所以形成线程等待,应用不可用。经过以上栈的信息,咱们就能够到程序代码中详细查看代码了,而且修改bug解决此问题。

死锁原理补充:

image

如图所示,形成死锁的缘由是线程之间存在相互制约的状况,而任一线程都没法继续执行。

小结

  本文介绍了Linux、Windows环境下经常使用的监控工具,最后经过一个案例简单说明故障排查的流程,怎么使用监控工具找出应用故障的缘由。

相关文章
相关标签/搜索