虚拟机性能监控与故障处理工具

JDK监控和故障处理工具

JDK的bin目录下有许多命令行工具,他们大多数是在tools类库实现的,借助这些工具,我们可以直接在应用程序中实现功能强大的监控分析功能。

监控和故障处理工具如下表所示:

名称主要作用
jpsJVM Process Status Tool,显示指定系统内所有的HotSpot虚拟机进程。
jstatJVM Statistics Monitoring Tool,用于收集HotSpot虚拟机各方面的运行数据
jinfoConfiguration Info forJava,显示虚拟机配置信息
jmapMemory Map for Java,生成虚拟机的内存转储快照(HeapDump文件)
jhatJVM Heap Dump Browser,用于分析HeapDump文件,它会建立一个HTTP/HTML服务器,让用户可以在浏览器上查看分析结果
jstackStack Trace for Java,显示虚拟机的线程快照
jps虚拟机进程状况工具

jps与UNIX的ps类似,可以列出正在运行的虚拟机进程,并显示虚拟机执行主类名称以及这些进程的本地虚拟机唯一ID(Local Virtual Machine Identifier, LVMID),jps还可以通过RMI协议查询开启了RMI服务的远程虚拟机进程状态。具体命令如下:

选项作用
-q只输出LVMID,省略主类名称
-m输出虚拟机进程启动时传递给主类main()函数的参数
-l输出主类的全名,如果进程执行的是Jar包,输出Jar路径
-v输出虚拟机进程启动时JVM参数
jstat:虚拟机统计信息监视工具

jstat是用于监视虚拟机各种运行状态信息的命令行工具,它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

jstat命令格式为:jstat [option vmid [interval[s|ms]] [count]]

每250ms查询一次进程2764垃圾收集情况,查询20次的命令就是:

jstat -gc 2764 250 20

interval代表查询间隔,count代表次数,省略这两个参数,说明只查询一次。option代表用户希望查询的虚拟机信息,主要分为3类:类装载、垃圾收集、运行期编译状况。主要选项如下表所示:

选项作用
-class监视类装载、卸载数量、总空间以及类装载所耗费的时间
-gc监视Java堆状况,包括Eden区、两个Survivor区、老年代等的容量、已用空间、GC时间合计等信息
-gccapacity与-gc基本相同,主要关注Java堆各个区域使用到的最大最小空间
-gcutil与-gc基本相同,主要关注已使用空间占总空间的百分比
-gccause与-gcutil功能一样,额外输出导致上一次gc产生的原因
-gcnew监视新生代gc状况
-gcnewcapacity与-gcnew基本相同,主要关注使用到的最大、最小空间
-gcold监视老年代GC状况
-gcoldcapacity与-gcold基本相同,主要关注使用到的最大、最小空间
-compiler输出JIT编译器编译过的方法、耗时等信息
-printcompilation输出已经被JIT编译的方法
jinfo:Java配置信息工具

jinfo的作用是实时的查看和调整虚拟机各项参数,-flag命令未被显示指定的参数的系统默认值,-sysprops把虚拟机进程的System.getProperties()的内容打印出来。

jmap:Java内存映像工具

jmap命令用于生成堆转储快照,也可以设置虚拟机参数生成dump文件。jmap还可以查询finalize执行队列、Java堆的详细信息,如空间使用率、当前用的是哪种收集器等。Windows只能使用-dump选项和-histo选项。下面是主要选项:

选项作用
-dump生成Java堆转储快照,格式为-dump:[live,]format=b,file=,live说明只dump出活的对象
-finalizerinfo显示在F-Queue中等待Finalizer线程中执行finalize方法的对象
-heap显示Java堆详细信息,如使用哪种回收器、参数配置、分代状况等
-histo显示堆中对象统计信息,包括类、实例数量、合计容量
-F强制生成dump快照
jhat:虚拟机堆转储快照分析工具

jhat与jmap搭配,可分析dump出来的快照,可以用内存分析工具代替jhat如JProfiler、VisualVM等。

jstack:Java堆栈跟踪工具

jstack用于生成虚拟机当前时刻的线程快照,线程快照是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待。线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,可以知道没有响应的线程到底在后台做什么事情,或等待什么资源。主要选项如下:

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

Thread类的getAllStackTraces()也可以实现jstack的大部分功能,生成的是一个map,键为线程,值为线程堆栈。

JDK可视化工具

JConsole:Java监视与管理控制台(Java Monitoring and Management Console)

JConsole是一种基于JMX的可视化监视管理工具,它对JMX MBean进行管理。下面是JConsole的运行界面:
这里写图片描述

概览一栏显示整个虚拟机主要运行数据,内存一栏相当他jstat,可以监视虚拟机内存的变化趋势,线程一栏相当于可视化的jstack,遇到线程停顿可以用它进行监控分析。下面是一些代码分析示例:

package toolstest;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author Zhang
 * @date 2018/8/18
 * @Description
 */
public class ThreadTest {

    public static void createBusyThread(){
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true);
            }
        },"testBusyThread");

        thread.start();
    }

    //线程锁等待演示
    public static void createLockThread(final Object lock){
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock){
                    try {
                        lock.wait();
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        },"testLockThread");

        thread.start();
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        br.readLine();
        createBusyThread();
        br.readLine();
        Object obj = new Object();
        createLockThread(obj);
    }
}

代码运行后,查看main线程,如下图,堆栈跟踪显示在等待System.in输入,状态为RUNNABLE。
这里写图片描述
接着执行testBusyThread线程,可以看到线程一直在执行18行的空循环:
这里写图片描述
执行testLockThread线程,可以看到它处于阻塞状态,等待被notifyAll方法唤醒:
这里写图片描述

一个死锁的执行测试:

package toolstest;

import java.util.concurrent.locks.Lock;

/**
 * @author Zhang
 * @date 2018/8/18
 * @Description
 */
public class DeadLock {
    public static String obj1 = "obj1";
    public static String obj2 = "obj2";
    public static void main(String[] args){
        Thread a = new Thread(new Lock1());
        Thread b = new Thread(new Lock2());
        a.start();
        b.start();
    }
}
class Lock1 implements Runnable{
    @Override
    public void run(){
        try{
            System.out.println("Lock1 running");
            while(true){
                synchronized(DeadLock.obj1){
                    System.out.println("Lock1 lock obj1");
                    Thread.sleep(3000);//获取obj1后先等一会儿,让Lock2有足够的时间锁住obj2
                    synchronized(DeadLock.obj2){
                        System.out.println("Lock1 lock obj2");
                    }
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
class Lock2 implements Runnable{
    @Override
    public void run(){
        try{
            System.out.println("Lock2 running");
            while(true){
                synchronized(DeadLock.obj2){
                    System.out.println("Lock2 lock obj2");
                    Thread.sleep(3000);
                    synchronized(DeadLock.obj1){
                        System.out.println("Lock2 lock obj1");
                    }
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

如下图所示,可点击检测死锁监测到发生死锁的线程:
这里写图片描述
由图可知,两个线程互相等待释放锁,形成死锁。

VisualVM:多合一故障处理工具(All-in-One Java Troubleshooting Tool)

VisualVM具有运行监视、故障处理、性能分析等功能,甚至不比JProfiler逊色,而且不需要被监视的程序基于特殊Agent运行,因此它对应用程序的实际性能的影响很小。

通过插件扩展,可以实现以下功能:

  • jps、jinfo的功能;
  • jstat、jstack的功能;
  • jmap、jhat的功能;
  • 方法级程序分析;
  • 离线程序快照等等。

安装插件,先在设置中修改插件地址,如下图所示,网址改为自己想要的版本地址,下载地址如下,选择版本复制地址即可:

https://visualvm.github.io/pluginscenters.html

这里写图片描述

然后点击可用插件选择自己要安装的插件,如图:
这里写图片描述

安装即可,运行界面如图所示,一般功能与JProfiler类似:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值