JVM 工具

1. 基础故障处理工具

1.1 jps(虚拟机进程状况工具)

       jps的功能与UNIX中的ps 命令类似。

       可以列出正在运行的虚拟机进程,并显式虚拟机指向主类(main函数所在的类)名称以及这些进程在本地虚拟机唯一ID

命令格式

       jps [options] [hostid]

       jps还可以通过RMI协议查询开启了RMI服务的远程虚拟机进程状态,参数hostidRMI注册表中注册的主机名。

选项作用
-q只输出java在本地虚拟机的唯一id
-m输出虚拟机进程启动时传递给主类main()函数的参数
-l输出主类的全名,如果进程执行的是Jar包,输入Jar路径
-v输出虚拟机进程启动时JVM参数

示例

在这里插入图片描述

1.2 Jstat(虚拟机统计信息监视工具)

       Jstat用于监视虚拟机各种运行状态信息。可以显式虚拟机进程中的类加载、内存、垃圾回收,即时编译等运行数据。

命令格式

       jstat [ option vmid [ interval [ s | ms ] [ count ]]]

       如果是本地虚拟机进程,VMID则为jps查出的进程对应的id

       如果是远程虚拟机进程,那么VMID的格式应是:[protocol:] [//] lvmid [@hostname [:port]/servername]

       intervalcount 代表查询间隔和次数,如果省略,则说明只查询一次。

       option代表用户查询虚拟机的信息,主要分为类装载、垃圾收集、运行期编译状况。

选项作用
-class监视类装载、装载数量、总空间及类装载耗费时间
-gc监视Java堆状况,包括Eden区,两个sruvivor区、老年代、永久代等容量、医用空间、GC时间合计
-gccapacity监视内容与-gc基本相同,但输出主要关注Java堆各个取余使用的最大、最小空间
-gcutil监视内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比
-gccause-gcutil功能一样,但是会额外输出导致上一次GC产生的原因
-gcnew监视新生代GC状况
-gcnewcapacity监视内存与-gcnew基本相同,输出主要关注使用到的最大、最小空间
-gcold监视老生代GC状况
-gcoldcapacity监视内容与-gcold基本相同,输出主要关注使用到的最大、最小空间
-gcpermcapacity输出永久代使用的最大、最小空间
-comiler输出JIT编译器编译过的方法、耗时等信息
-printcompilation输入已经被JIT编译的方法

示例

在这里插入图片描述

       E:新生代Eden区,使用了8.01%空间

       S0、S1:表示两个Survivor区

       O:老年代

       M:元数据区使用比例

       CCS:压缩使用比例

       YGC:年轻代垃圾回收次数

       YGCT:年轻代垃圾回收消耗时间

       FGC:老年代垃圾回收次数

       FGCT:老年代垃圾回收消耗时间

       GCT:垃圾回收消耗总时间

1.3 jinfo(Java 配置信息工具)

       jinfo的作用是实时查看和调整虚拟机各项参数。

命令格式

       jinfo [option] pid

选项作用
no option输出全部的参数和系统属性
-flag name输出对应名称的参数
-flag [+|-] name开启或者关闭对应名称的参数
-flags输出全部的参数
-sysprops输出系统属性

示例

在这里插入图片描述

1.4 jmap(Java 内存映像工具)

       jmap最主要的作用是获取对转储快照,除此之外,还可以查询finalize执行队列、Java堆和方法区的详细信息,如空间使用率,当前用到是哪种收集器。

命令格式

       jmap [option] vmid

选项作用
-dump生成 Java 堆转储快照。格式为 -dump:[live,]format=b,file=<filename>,其中 live子参数说明是否只dump出存活的对象
-finalizerinfo显示在F-Queue队列等待Finalizer线程执行finalize方法的对象
-heap显示Java堆详细信息
histo[:live]显示堆中对象的统计信息
F当-dump没有响应时,使用-dump或者-histo参数,在这个模式下,live子参数无效.

示例

在这里插入图片描述

1.5 Jhat(虚拟机堆转储快照分析工具)

       jhat命令与jmp搭配使用,来分析jmap生成的堆转储快照。

在这里插入图片描述在这里插入图片描述

1.6 jstack(Java 堆栈跟踪工具)

       jstack用于生成虚拟机当前时刻的线程快照,生成线程快照的目的通常是定位线程长时间停顿的原因,如线程间死锁、死循环、请求外部资源等导致的长时间挂起等,都是导致线程长时间停顿的常见原因。

       通过jstack可以获知没有响应的线程在后台做些什么事情,或者等待着什么资源。

命令格式

       jstack [option] vmid

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

示例

在这里插入图片描述

2. 可视化故障处理工具

2.1 JConsole(Java 监控与管理控制台)

       JConsole是一个堆Java进程进行监视、管理的可视化工具。

2.1.1 启动 JConsole

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.1.2 内存监控

       "内存"页签的作用相当于可视化的jstat命令,用于监视被虚拟机管理的虚拟内存的变化趋势。

       运行如下代码,同时设置虚拟机参数为:-Xms100m -Xmx100m -XX:+UseSerialGC

import java.util.ArrayList;
import java.util.List;

/**
 * @author wangzhao
 * @date 2020/7/3 22:27
 */
public class MemoryAnalysis {

    static class OOMObject{
        public byte[] placeholder = new byte[64 * 1024];
    }

    public static void fileHeap(int num) throws InterruptedException {
        List<OOMObject> list = new ArrayList<OOMObject>();
        for (int i = 0; i < num; i++){
            // 稍作演示,令监视曲线的变化更加明显
            Thread.sleep(50);
            list.add(new OOMObject());
        }
        System.gc();
    }

    public static void main(String[] args) throws InterruptedException {
        fileHeap(1000);
    }
}

在这里插入图片描述

2.1.3 线程监控

       "线程"页签的作用相当于可视化的jstack命令,遇到线程停顿的时候可以使用这个页签的功能进行分析。


import java.io.IOException;
import	java.io.InputStreamReader;
import	java.io.BufferedReader;/**
 * @author wangzhao
 * @date 2020/7/3 22:35
 */
public class ThreadAnalysis {

    // 线程死循环演示
    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线程中,堆栈追踪显式BufferedReaderreadBytes()正在等待System.in的键盘输出,这时候线程为Runnable状态,Runnable状态的线程仍会被分配运行时间。但readBytes()检查到流没有更新就立刻归还执行令牌给操作系统,这种等待只消耗很小的处理器资源。

在这里插入图片描述       testBusyThread线程一直在执行空循环,可以看到其停留在16行,16的代码为while (true)的循环体。这时候线程为Runnable状态,而且没有归还线程执行令牌的动作,所以会在空循环耗尽操作系统分配给它的执行时间,直到线程切换为止,这种等待会消耗大量的处理器资源。

在这里插入图片描述       testLockThread线程在等待lock对象的notify()notifyAll()方法的出现,线程这时候处于WAITING状态,在重新唤醒前不会被分配执行时间。

       死锁示例:

/**
 * @author wangzhao
 * @date 2020/7/3 22:49
 */
public class DeadLockAnalysis {

    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 main(String[] args) {
        for (int i = 0; i < 100; i++){
            new Thread(new SynAddRunnable(1, 2)).start();
            new Thread(new SynAddRunnable(2, 1)).start();
        }
    }

}

在这里插入图片描述
在这里插入图片描述
       由于Thread-56Thread-65分别在等待对方释放锁,从而形成死锁。

2.2 VisualVM(多合一故障处理工具)

       除了运行监视、故障处理外,还可以进行性能分析、生成、浏览对转储快照、BTrace动态日志跟踪等。

       由于需要自行去下载,故这里不再介绍。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值