本小节会介绍JVM性能监控,掌握几种常用的监控工具辅助我们更好的了解JVM的性能状态。生产环境中监控JVM性能,分析监控数据,可以知道何时需要JVM调优,可见监控是非常重要的。
JVM的监控范围包括垃圾收集、JIT编译以及类加载。那其中具体都包含哪些?如何监控呢?我们开始探索下吧
监控JVM的垃圾收集非常的重要,因为它对应用的吞吐量和延迟有着深刻的影响。
重要的垃圾收集数据包括:
当前使用的垃圾收集器
JAVA堆的大小
新生代和老年代的大小
永久代的大小
Minor GC的持续时间
Minor GC的频率
Minor GC的空间回收量
Full GC的持续时间
Full GC的频率
每个并发垃圾收集周期的空间回收量
是否老年代或者永久代的占用触发了Full GC
应用是否显式调用了System.gc()
…
除了用命令行选项生成垃圾收集统计数据,我们还可以用图形化工具监控垃圾收集,用这类工具识别变化趋势或者模式要比文本容易很多。下列图形化工具可用于监控HotSpot VM:JConsole、JProfile(收费)、VisualGC(插件)以及VisualVM
3.1 VisualVM介绍
在进行多线程编程以及线程池编程时候,是无法用肉眼确认程序性能的,也不会知道当前jvm上面有多少个线程,线程池用的对不对。这时候就要用 visual vm 这些jdk自带的性能监测工具了。
简单介绍:
请打开你的jdk的bin目录找到以下图标,双击打
然后你会看到
点击左侧是用到jvm的程序intellij platform–就是用这的idea java编辑器:
总共有四个标签,重点介绍以下“监视”以及“线程”
监视里面的线程一栏看看,活动是指目前活动活跃的线程数量,已经启动的总数是指,程序运行以来一共创建或启动的线程数量,无论线程状态是不是完成了,或者已经被销毁了,还是说正在活动中,抑或在阻塞,全部都统计在这个数字中
线程标签页如下:
线程标签页可以选择所有线程列表,活动的线程或者是已经完成的线程,这些信息也对于判断程序的性能很重要
3.2 JConsole介绍
JConsole主要用来分析内存,cpu,线程,类等
在JDK安装目录找到jconsole.exe
概览:在连接上Java应用程序后,遍可以查看应用程序概况,如下图所示。图中4张折线分别显示了堆内存的使用情况、系统线程数量、加载类的数量以及CPU的使用率。
内存监控:切换到内存监控页面,JConsole可以显示当前内存的详细细心。这不仅包括堆内存的整体信息,更细化到eden区,survivior区、老年代的使用情况。同时,也包括非堆区,即永久代的使用情况。单机界面右上角“执行GC”按钮,可以强制应用程序进行一次Full GC。
线程监控:JConsole中的线程选项卡允许开发人员监控程序内的线程,如下图所示。JConsole显示了系统内的线程数量以及程序中所有的线程。单机线程名称,便可以查看线程的栈信息。
使用“检测到死锁”按钮,还可以自动检测多线程应用程序的死锁情况(可快速定位死锁问题)
类加载情况:JConsole的类页面显示了系统已经装载的类数量。在详细信息栏中,还显示了已经卸载的类数量。
虚拟机信息:在VM摘要页面,JConsole显示了当前应用程序的运行环境。包括虚拟机类型、版本、堆信息以及虚拟机参数等
MBean管理:MBean页面允许JConsole进行MBean的管理,包括查看或者设置MBean的属性、运行MBean的方法等。
3.3 性能采集工具
1)linux命令工具
top命令:
top命令参数
-h | -v: 显示帮助或者版本信息】** -c:** 命令行列显示程序名以及参数-d: 启动时设置刷新时间间隔-H: 设置线程模式-i: 只显示活跃进程-n: 显示指定数量的进程-p: 显示指定PID的进程-u: 显示指定用户的进程
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况。top命令的部分输出如下:
top视图分为两部分:操作系统资源概况信息和进程信息。首先分析资源概况中各个参数的含义,再来分析下进程信息中各个参数含义。
资源概况:
操作系统时间、登录用户、负载情况-top00:36:13: 操作系统当前时间up xx days, HH:MM: 操作系统从开机以后运行的时间,运行多少天多少时多少分users: 当前系统有1个用户登录在线**load average:**系统平均负载运行的任务概览-Taskstotal: 系统当前的进程数running: 当前正在运行的进程数sleeping 当前睡眠中的进程数CPU概览: %Cpu(s) 表示CPU使用百分比,按照时间占用计算,单位sus: 用户空间占用CPU时间百分比,如果是多核,这个数值表示占用的平均百分比,可以按1进行多核统计和平均统计切换sy: 内核空间占用CPU时间百分比,如果是多核,同上ni 用户进程空间内改变过优先级的进程占用CPU时间百分比id: 空闲时间占用CPU百分比wa: 等待输入输出的CPU时间百分比hi: CPU服务于硬件中断的CPU时间百分比si: CPU服务于软件中断的CPU时间百分比
注:时间占用百分比=该种类型操作消耗CPU时间/top刷新间隔时间。top 3s刷新一次,用户空间进程在这3s内使用了CPU 1.5s,那么us等于50%=1.5s/3s内存概览:单位KiBtotal: 内存总量free: 剩余的内存数量used: 内存使用数量buff/cache: 用于缓冲的内存数量交换区概览:单位KiBtotal: 交换区总量free: 空闲的交换区数量used: 使用的交换区数量
进程概况
进程概况的统计从多维度参数进行展示的,其中最重要的参数:
PID 进程ID,唯一标识USER 进程所属用户%CPU 自上一次top刷新该进程占用CPU的时间百分比%MEM 进程消耗内存百分比TIME+ 自进程开始以来,消耗CPU时间,单位1/100秒
当服务器中某个JAVA服务进程内存或者CPU资源消耗非常严重时,可以使用:top -H -p pid 查看其所有活跃的线程资源消耗情况
sar命令:sar(System Activity Reporter系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:文件的读写情况、系统调用的使用情况、磁盘I/O、CPU效率、内存使用状况、进程活动及IPC有关的活动等。
常用格式sar [options] [-A] [-o file] t [n]
例如,每10秒采样一次,连续采样3次,观察CPU 的使用情况,并将采样结果以二进制形式存入当前目录下的文件test中,需键入如下命令:
sar -u -o test 10 3
vmstat命令:是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况。相比top,我可以看到整个机器的CPU,内存,IO的使用情况,而不是单单看到各个进程的CPU使用率和内存使用率(使用场景不一样)。
一般vmstat工具的使用是通过两个数字参数来完成的,第一个参数是采样的时间间隔数,单位是秒,第二个参数是采样的次数,如:
IOStat命令:iostat主要用于监控系统设备的IO负载情况,iostat首次运行时显示自系统启动开始的各项统计信息,之后运行iostat将显示自上次运行该命令以后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息。
举例: iostat -d -k 2
参数 -d 表示,显示设备(磁盘)使用状态;-k某些使用block为单位的列强制使用Kilobytes为单位;2表示,数据显示每隔2秒刷新一次。
pidstat命令:pidstat是sysstat工具的一个命令,用于监控全部或指定进程的cpu、内存、线程、设备IO等系统资源的占用情况。pidstat首次运行时显示自系统启动开始的各项统计信息,之后运行pidstat将显示自上次运行该命令以后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息。
如:查看所有进程的 CPU 使用情况( -u -p ALL)
2)windows工具
任务管理器:Windows系统的任务管理器是大家最为熟知的一款系统工具,通过Ctrl+Alt+Del组合键便能呼出,功能非常强大的一款新能统计工具。
perfmon性能监控工具:与任务管理器相比,可以说是windows下专业级的性能监控工具了,不仅可以监控计算机系统的整体运行情况,也可以专门针对某一个进程或者线程进行状态监控。
可以在Windows任务栏的开始菜单的“运行”对话框使用perfmon命令打开该工具。
3)JDK命令行工具
在JDK的开发包中有一系列的辅助工具,可以帮助开发人员很好地解决Java应用的一些疑难杂症。这些工具在JDK安装目录的bin目录中。有哪些命令可以辅助呢?如下所示:
jps命令:jps是用于查看有权访问的hotspot虚拟机的进程. 当未指定hostid时,默认查看本机jvm进程,否者查看指定的hostid机器上的jvm进程,此时hostid所指机器必须开启jstatd服务。 jps可以列出jvm进程lvmid,主类类名,main函数参数, jvm参数,jar名称等信息
命令用法: jps [options] [hostid]
options:命令选项,用来对输出格式进行控制
hostid:指定特定主机,可以是ip地址和域名, 也可以指定具体协议,端口。
jstat命令:jstat是一个可以用于观察Java应用程序运行时信息的工具。它的功能非常强大,可以通过它,查看堆信息的详细情况
jinfo命令:jinfo是jdk自带的命令,可以用来查看正在运行的Java应用程序的扩展参数,甚至支持在运行时,修改部分参数。通常会先使用jps查看java进程的id,然后使用jinfo查看指定pid的jvm信息.
jmap命令:Jmap是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。打印出某个java进程(使用pid)内存内的,所有‘对象’的情况( 如:产生那些对象,及其数量)。
jhat命令:jhat也是jdk内置的工具之一。主要是用来分析java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言
jstack命令:jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式:jstack [-l] pid
如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。**jstatd命令:**此命令是一个RMI Server应用程序,提供了对JVM的创建和结束监视,也为远程监视工具提供了一个可以attach的接口
hprof工具:HProf是JDK自带一个简单的性能分析工具。它是一个动态链接库文件,监控CPU的1使用率、内存堆栈分配情况等
命令的详细使用方法可搜索相关资料,此处不再展开讲解
本小节主要介绍了常用的性能采集工具和故障排查工具。基于linux系统和Windows系统的性能采集工具,使用这些工具,有助于帮助开发者定位性能瓶颈。JDK自带的一些性能和故障排查相关命令,如jps、jstack、jmap等,以及免费的可视化工具JConsole、Visual VM。下一小节我们会介绍JVM调优方法。