JVM监控常用的6个命令行工具


本文中命令演示基于JDK8,不同的JDK版本可能存在差别

jps 查看虚拟机进程状况

概述

可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机唯一 ID(LVMID,Local Virtual Machine Identifier)。
如果某Java进程在启动是关闭了UsePerfData参数(即-XX:-UsePerfData),那么jps(以及下一小节介绍的jstat)将无法探知该Java进程。
官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html

基本语法

通过jps -help查看命令格式。
在这里插入图片描述

选项作用
-q只输出LVMID,省略主类名
-m输出虚拟机进程启动时传递给主类main()函数的参数
-l输出主类的全名,如果进程执行的是jar包,则输出jar路径
-v输出虚拟机进程启动时的JVM参数

jstat 查看虚拟机统计信息

概述

可以显示本地或者远程虚拟机进程中的类加载、内存、垃圾收集、即时编译等运行时数据。
官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

基本语法

通过jstat -help查看命令格式。
在这里插入图片描述

选项作用
-t可以在输出信息前加上Timestamp列,显示程序的运行时间。单位:秒
-h可以在周期性数据输出时,输出多少行数据后输出一个表头信息
vmid进程ID,通过jps -l查询
interval用于指定输出统计数据的周期(查询间隔),单位:毫秒
count用于指定查询的总次数

通过jstat -options查看具体执行命令。
在这里插入图片描述

选项作用
-class监视累加载、卸载数量、总空间以及类装载耗时
-gc监视Java堆状况,包括Eden区、2个survivor区、老年代、元空间等的容量,已用空间,垃圾收集时间合计等信息
-gccapacity监视内容和-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间
-gcutil监视内容和-gc基本相同,但输出主要关注已使用空间占总空间的半分比
-gccause和-gcutil功能一样,但是会额外输出导致上一次gc产生的原因
-gcnew监视新生代垃圾收集状况
-gcnewcapacity监视内容和-gcnew基本相同,输出主要关注使用到的最大、最小空间
-gcold监视老年代垃圾收集状况
-gcoldcapacity监视内容和-gcold基本相同,输出主要关注使用到的最大、最小空间
-gcmetacapacity输出元空间使用到的最大、最小空间
-compiler输出即时编译器编译过的方法、耗时等信息
-printcompilation输出已经被即时编译的方法

示例1

代码

 public class MonitorTest {
    public static void main(String[] args) {
        try {
            Thread.sleep(5 * 60_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

命令演示

执行-class命令,-t会显示Timestamp列,-h2每隔两行打印下title,27547是通过jps -l查到的LVMID10是每隔10毫秒查询一次,5是查询总次数。
在这里插入图片描述

示例2

代码

// 设置虚拟机运行参数 -Xm30m -Xmx30m -XX:SurvivorRatio=8
    public static void main(String[] args) {
        ArrayList<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            byte[] arr = new byte[1024 * 100];//100KB
            list.add(arr);
            try {
                Thread.sleep(120);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

命令演示

在这里插入图片描述
Titile对应的含义可以查看官方文档https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html,在此就不做翻译了。
在这里插入图片描述

经验

  1. 可以比较Java进程启动时间(Timestamp列)和总GC时间(GCT列),或是两次测量的间隔时间和总GC时间的增量,来计算出GC时间占运行时间的比例。如果比例超过20%则表明目前堆的压力较大,如果该比例超过90%,则说明堆里几乎没有可用空间,随时可能出现OOM。
  2. 可以多次运行jstat命令,取出每次运行后得到数据行中 OU 列的最小值,比较这个值,如果这些值呈上升趋势,则说明该Java程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄露。

jinfo 实时查看、修改虚拟机参数

概述

实时查看和调整虚拟机各项参数。
官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jinfo.html

基本语法

使用jinfo -help查看命令格式。
在这里插入图片描述
命令格式描述的很清晰,下面简单翻译下。

  • 查看
    • jinfo -flag 具体参数名 PID,查看某个java进程的具体参数的值。
    • jinfo -flags PID,查看赋过值的一些参数。
    • jinfo -sysprops PID,查看在程序中可以通过System.getProperties()取到的参数。
  • 修改
    • 参数为boolean类型,jinfo -flag [+|-]具体参数 PID,[+|-]中+表示开启,-表示关闭。
      • eg: jinfo -flag +HeapDumpOnOutOfMemoryError 28374
    • 参数为赋值类型,jinfo -flag 具体参数=要设置的值 PID
    • 具体可以修改的参数请看笔者整理的常用的JVM参数设置
    • 只有标记为manageable的参数才能修改,查看命令java -XX:+PrintFlagsFinal -version | grep manageable
      在这里插入图片描述

jmap 导出内存映像文件&查看堆内存使用情况

概述

用于生成堆转储快照(一般称为heapdump或dump文件),还可以查询finalize执行队列、Java堆和方法区的详细信息,如空间使用率、当前用的是哪种收集器等。
官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jmap.html

基本语法

使用jmap -help查看命令格式。
在这里插入图片描述

选项作用
-heap显示整个堆的详细信息,包括GC的使用,堆配置信息,以及内存使用信息
-histo显示堆中对象统计信息,包括类、实例数量、合计容量
-clstats显示堆中类加载器统计信息
-finalizerinfo显示等待执行finalize方法的对象
-dump生成Java堆转出快照,jmap -dump:live,format=b,file=filename.hprof PID,live参数表示是否只dump存活的对象
-F当虚拟机对-dump选项没有响应时,可以使用此选项强制生成dump快照

示例

代码

    // 设置虚拟机运行参数 -Xm30m -Xmx30m -XX:SurvivorRatio=8
    public static void main(String[] args) {
        ArrayList<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 1000; i++) {
            byte[] arr = new byte[1024 * 100];//100KB
            list.add(arr);
            try {
                Thread.sleep(120);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

命令演示

在这里插入图片描述
上面是手动演示,通常情况下是在进程启动时配置好参数,-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<path/filename.hprof>,这样在发生OOM是就会自动生成堆转储快照,便于后续分析排查问题。
在这里插入图片描述

jhat 虚拟机堆分析工具

和jmap配套使用,实际开发过程中不会直接在服务器上执行jhat,jhat执行会消耗大量内存,导致服务器不可用。如果是将导出的dump文件下载到本地进行分析,那就无需使用jhat了,使用有更强大功能的MAT导入dump文件进行分析。下一篇会讲解MAT如何使用。

jstack 生成虚拟机线程快照

概述

用于生成虚拟机当前时刻的线程快照(一般称为thread dump文件)。线程快照就是当前虚拟机内每一个线程正在执行的方法堆栈的集合,生成线程快照的目的通常是定位线程出现长时间停顿的原因(如线程间死锁、死循环、请求外部资源导致的长时间挂起等),线程出现停顿时通过jstack来查看各个线程的调用堆栈情况。
在thread dump文件中需要留意以下几种状态,笔者转载的这篇文章讲解的比较详细 深入理解jstack日志
1. Deadlock(死锁)
2. Waiting on condition(等待资源)
3. Blocked(阻塞)
4. Waiting on monitor entry(等待获取锁)

5. Runnable(执行中)
6. Suspended(暂停)
7. TIMED_WWAITING 或 Object.wait()(对象等待中)
8. Parked(停止)

官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstack.html

基本语法

使用jstack -help查看命令格式
在这里插入图片描述

选项作用
-F当正常输出的请求不被响应时,强制输出线程堆栈
-l除堆栈外,显示关于锁的附加信息
-m如果调用到本地方法,可以显示C/C++的堆栈

示例1(死锁)

代码

public class JstackTestDeadLock {
    private static String lockA = "锁对象A";
    private static String lockB = "锁对象B";

    public static void main(String[] args) {
        new Thread() {
            public void run() {
                while (true) {
                    synchronized (lockA) {
                        System.out.println(this.getName() + ":得到lockA");
                        synchronized (lockB) {
                            System.out.println(this.getName() + ":得到lockB");
                        }
                    }
                }
            }
        }.start();

        new Thread() {
            public void run() {
                while (true) {
                    synchronized (lockB) {
                        System.out.println(this.getName() + ":得到lockB");
                        synchronized (lockA) {
                            System.out.println(this.getName() + ":得到lockA");
                        }
                    }
                }
            }
        }.start();
    }
}

命令演示

在这里插入图片描述

实例2(TIMED_WWAITING)

代码

    public static void main(String[] args) {
        System.out.println("hello");
        try {
            Thread.sleep(60_000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("world");
    }

命令演示

jstack -l PID

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值