虚拟机异常检查工具
阅读原文时间:2021年04月20日阅读:1

虚拟机异常检查工具

命令行工具

jps(JVM Process Status)虚拟机进程状态工具

功能

查询LVMID(虚拟机进程ID)

命令格式

jps options hostid(例如: jps -l)

工具选项

选项

功能

-q

只输出LVMID

-m

输出虚拟机进程启动时传递给主类main()函数的参数

-l

输出主类的全名,如果进程执行的Jar包,输出Jar路径

-v

输出虚拟机进程启动时JVM参数(显示指定)

jstat(JVM statistics monitoring)虚拟机统计信息监视工具

功能

显示本地或者远程虚拟机进程中的类装载,内存,垃圾收集,JIT编译等运行数据.

命令格式

jstat options vmid [interval count]/(例如: jstat -gc 2764 250 20 -> 每250毫秒查询一次经常2764垃圾收集状况,一共查询20次,后面两个参数是可选参数,如果不传,默认值查询一次)

工具选项

选项

功能

-class

监视类装载,卸载数量,总空间以及类装载所耗费的时间

-gc

监视Java堆状况,包括Eden区、两个Survivor区、老年代、永久带(或元空间)等的容量、已用空间、GC时间合计等信息

-gccapacity

监视内容与-gc 基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间

-gcutil

监视内容与-gc 基本相同,但输出主要关注已使用空间占总空间的百分比

-gccause

与-gcutil功能一样,但是会额外输出导致上一次GC产生的原因

-gcnew

监视新生代GC状况

-gcnewcapacity

监视内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间

-gcold

监视老年代GC状况

-gcoldcapacity

监视内容与-gcold基本相同,输出主要关注使用到的最大、最小空间

-gcpermacapacity
(-gcmetacapacity)

输出永久带使用到的最大、最小空间
输出元空间使用到的最大、最小空间

-compiler

输出JIT编译器编译过的方法、耗时等信息

-printcompilation

输出已被JIT编译的方法

jinfo(Configration info)Java配置信息工具

功能

实时查看和调整虚拟机各项参数

命令格式

jinfo options pid(例如: jinfo -flag CMSInititingOccupancyFraction 1444 -> 查询该配置的参数值)

工具选项

选项

功能

-flag name

打印参数配置的值

-flag (+name/-name)

增加参数配置

-flag name=value

给参数动态添加配置

-flags

打印所有虚拟机参数配置值

-sysprops

打印Java系统配置值

(不输入任何参数)

输出上面两个的配置值

jmap(Memory map)Java内存映射工具

功能

用于生成堆转储快照(一般称为heapdump或dump文件),还可以查询finalize执行队列、Java堆和永久带(元空间)的详细信息,如空间使用率、当前用的那种收集器等

命令格式

jmap options vmid(例如: jmap -heap 6336 -> 输出vmid为6336的堆的详细信息)

jhat(JVM Heap analysis)虚拟机堆转储快照分析工具

功能

与jmap搭配使用,分析jmap生产的堆转储快照。其内置了一个微型的HTTP/HTML服务器。可以在浏览器中查看

命令格式

jhat path(dump文件路径)

缺陷

  1. 分析工作是一个耗时而且消耗硬件资源的过程(加载dump文件需要生成比dump更大的内存)
  2. jhat的分析功能相对来说比较简陋

jstack(Stack trace for java)Java堆栈跟踪工具

功能

生成虚拟机当前时刻的线程快照(一般称为threaddump或者javacore文件),生成的主要目的是定位线程长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等都是导致长时间停顿的常见原因。线程停顿时通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么或等待着什么资源

  • 线程快照: 当前虚拟机内每一条线程正在执行的方法堆栈的集合

命令格式

jstack [options] vmid(例如: jstack -l 6336 -> 查看vmid为6336的线程堆栈信息)

可视化工具

JConsole(Java monitoring and management console)Java监视与管理控制台

功能

基于JMX的可视化监视,管理工具。他管理部分的功能是针对JMX MBean进行管理。

使用

  • 启动JConsole

    • 通过JDK/bin下的jconsole.exe启动,选择一个进程双击或者点连接即可,还可以使用连接到远程服务器,对虚拟机进行监控。进入后可以看见该工具主要包括概述内存线程VM摘要MBean6个页签。
  • 概述页签

    • 该页签主要显示的这个虚拟机主要运行数据的概览,其中包括堆内存使用情况线程CPU使用情况4众信息的曲线图。
  • 内存页签

    • 相当于可视化的jstat命令,用于监视收集器管理的虚拟机内存(堆内存和非堆内存)的变化趋势。
  • 线程监控

    • 相当于可视化的jstack命令

    • BufferReader在等待System.in的键盘输入时,线程为Runnable状态,会被分配运行时间,但方法检查到流没有更新时会立刻归还执行令牌,这种等待只消耗很小的CPU资源。

    • while(true)时线程为Runnable状态,而且没有归还线程执行令牌的动作,会在空循环上用尽全部执行时间直到线程切换,这种等待会消耗较多的CPU资源。

    • Synchronized锁住时,线程处于WAITING状态,在唤醒之前不会被分配执行时间。

    • 死锁案例

      static class SynAddRunnable implements Runnable {
      int a, b;
      public SynAddRunnable(int a, int b) {
      this.a = a;
      this.b = b;
      }

      @Override
      public void run() {
          synchronized (Integer.valueOf(a)) {
              synchronized (Integer.valueOf(b)) {
                  System.out.println(a + b);
              }
          }
      }
      
      public static void mian(String[] args) {
          // 可以不用循环,但是触发死锁几率降低
          for (int i = 0; i < 100; i++){
              new Thread(new SynAddRunnable(1, 2)).start();
              new Thread(new SynAddRunnable(2, 1)).start();
          }
      }

      }

    为什么照搬这个例子,因为这个例子告诉我们,Integer.valueOf()方法基于减少对象创建次数和节省内存空间考虑,[-128, 127]之间的数字会被缓存(默认值,实际值取决于java.lang.Integer.IntegerCache.high参数的设置),当valueOf()方法传入的参数在这个范围之内,将直接返回缓存中的对象。

Visual VM(All-in-one Java Throubleshooting Tools): 多合一故障处理工具

功能

到目前为止随JDK发布的功能最强大的运行监视和故障处理程序,并且可以预见未来一段时间内都是官方主力发展的虚拟机故障处理工具。其还有一个很大的优点: 不需要被监视的程序给予特殊Agent运行,因此它对于应用程序的实际性能的影响很小,使得它可以直接运行在生产环境中。

特点

  • 显示虚拟机进程以及进程的配置,环境信息(jps、jinfo)
  • 监视应用程序的CPU、GC、堆、方法区以及线程的信息(jstat、jstack)
  • dump以及分析堆转储快照(jmap、jhat)
  • 方法级的程序运行性能分析,找出被调用最多,运行时间最长的方法
  • 离线程序快照: 手机程序的运行时间配置、线程dump、内存dump等信息建立一个快照,可以将快照保存
  • 可以安装插件
    • 点击工具 -> 插件 -> 可用插件进行自动安装

使用

  • 生成堆转储快照(如需保存,需要右击标签,然后另存)
    • 应用程序窗口中右键点击应用程序节点,然后选择堆Dump
    • 应用程序窗口中双击应用程序 -> 监视 -> 堆Dump
  • 浏览堆转储快照
    • 用以上方法或者装入dump文件即刻,会产生4个页签
    • 摘要
      • 应用程序dump时的运行时参数、Sustem.getProperties()的内容、线程堆栈等信息
      • 以类为统计口径统计类的实例数量、容量信息
    • 实例
      • 通过页签进入,可以看见此类中500个实例的具体属性信息
    • OQL控制台
      • OQL查询语句查询
  • 分析程序性能(一般不在生产环境使用)
    • Profiler页签中,查看程序运行期间方法级的CPU执行时间分析以及内存分析
    • 选择CPU或者内存按钮中的一个,然后切换到应用程序中对程序进行操作,点击停止按钮结束监控过程
    • 注意: 在Client模式下的虚拟机加入并且自动开启了类共享,此时多虚拟机进程中共享rt.jar中类数据以提高加载速度和节省内存的优化。为了保证性能,最好在被监视程序中使用-Xshare:off参数来关闭类共享优化

参考资料

周志明. 深入理解JVM虚拟机