经过前面的几篇博客,咱们介绍了Java虚拟机的内存分配以及内存回收等理论知识,了解这些知识对于咱们在实际生产环境中提升系统的运行效率是有很大的帮助的。可是话又说回来,在实际生产环境中,线上项目正在运行,咱们怎么去监控虚拟机运行效率?又或者线上项目发生了OOM,异常堆栈信息,咱们又怎么去抓取,而后怎么去分析定位问题呢?html
本篇博客,咱们就来介绍各类虚拟机监控和分析工具,固然都是命令行工具,不够直观,下篇博客咱们会介绍各类可视化工具。java
JVM Process Status Tools ,显示指定系统内全部的 HotSpot 虚拟机进程。
该命令有以下经常使用参数:windows
①、-l 服务器
显示应用程序main类的完整包名称或应用程序的JAR文件的完整路径名。oracle
②、-veclipse
显示虚拟机启动时的JVM参数。函数
③、-m工具
显示虚拟机进程启动时传递给主类 main() 函数的参数。性能
好比,我在服务器上启动了一个Tomcat,以下:spa
而后,输入 jps 命令,打印信息以下:
这里的 Bootstrap 即是启动的 Tomcat进程。能够加上 -v 参数,显示全部传递给 JVM的参数信息。
PS:jps 命令默认是没有安装的,须要进行安装,具体安装步骤能够百度,我这里就不作详细介绍了。
jps更多详细信息,请参考官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html
JVM Statistics Monitoring Tool,用于收集虚拟机各方面的运行数据。
jstat 是用于监视虚拟机各类运行时状态信息的命令行工具。它能够显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行时数据,它是运行时期定位虚拟机性能问题的首选工具。可是终究只是命令行工具,后面咱们会介绍图形化工具,更加直观。
该命令监控本地的格式以下:
jstat -参数 vmid 采样间隔时间 采样次数
①、经常使用参数有以下
②、vmid
表示目标虚拟机的标识符,在Linux系统上能够经过上小节咱们介绍的 jps 命令,前面输出的数字即是进程 PID。在windows平台上,能够经过任务管理器查看。
③、采样间隔时间
默认单位是毫毛,必须是正整数。
实例1:这里咱们加入 -class 参数,查看类装载信息:
相关表头信息:
Loaded:加载的类数量。
Bytes:加载的类字节KB大小。
Unloaded:卸载的类数量。
Bytes:卸载的类字节KB大小。
Time:执行类加载和卸载操做所花费的时间。
jstat更多详细信息,请参考官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html
jinfo(Confiiguration Info for Java):实时的查看和调整虚拟机各项参数
jinfo ,经过此命令,咱们能够实时的查看和调整虚拟机的各项参数(包括显示指定或默认配置的)。
该命令格式以下:
jinfo [ 选项 ] pid
①、经常使用选项以下
1、没有选项
打印系统属性名称键值对。
2、-参数名称
打印指定参数的名称和值。
3、-flag [+|-] 参数名称
启用或者禁用指定的布尔命令。
4、-flag name=value
设置参数name的值为value
5、-sysprops
打印Java属性名称键值对。
②、pid
进程号,和上面同样,能够经过jps命令获取。
jinfo更多详细信息,请参考官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jinfo.html
jmap(Memory Map for Java):用于生成堆存储快照
jmap主要用于获取堆存储快照文件,在生产环境中,发生OOM(堆内存溢出)异常时,咱们能够经过这个快照文件来快速定位到具体代码位置。
这个命令还能够查询 finalize 队列,Java堆和永久代信息,如空间使用率、当前用的是哪一种垃圾收集器等。
该命令格式以下:
jmap [参数] pid
①、经常使用参数以下:
对于堆内存溢出异常,在前面介绍虚拟机参数时,咱们介绍过,经过下面两个参数,也可以打印堆内存快照。
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath
下面,咱们经过以下代码,演示堆内存溢出异常:
1 package com.ys.algorithmproject.leetcode.demo.JVM; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /** 7 * Create by YSOcean 8 * 9 */ 10 public class JmapTest { 11 private static final int _1MB = 1024*1024; 12 13 /** 14 * 虚拟机参数设置: -Xms20M -Xmx20M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./ 15 * @param args 16 */ 17 public static void main(String[] args) { 18 List<Object> list = new ArrayList<>(); 19 while(true){ 20 list.add(new Object[_1MB]); 21 } 22 } 23 }
设置虚拟机参数后,而后运行这段代码,就会发生堆内存溢出异常,并在根目录下生成快照文件 java_pid10840.hprof。
那么,怎么经过 jmap 命令来生成堆内存快照呢?
jmap -dump:format=b,file=heap20190821.hprof 16823
后面的数字是进程PID,能够经过jps命令来获取。
获得堆内存快照了,那么咱们怎么去查看呢?
在eclipse中,能够下载 MAT 工具,而在 IDEA中,能够下载 JProfiler 插件。实在不行,能够用咱们下篇博客介绍的几个可视化工具,具体状况见下篇博客。
jmap更多详细信息,请参考官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html
Stack Trace for Java,用于生成虚拟机当前时刻的线程快照。
线程快照其实就是当前虚拟机每一条线程正在执行的堆栈的集合,经过线程快照能够用来定位线程出现长时间停顿的缘由(线程间死锁、死循环、请求外部资源致使的长时间等待)。
该命令格式以下:
jstack [选项] pid
①、经常使用选项以下:
参考文档:https://docs.oracle.com/javase/8/docs/technotes/tools/index.html