JVM基础到实战07-JDK自带的jvm分析工具

java虚拟机自带的工具,将jdk的lib下的tools包解压后可以发现工具的源码,或者直接在bin目录下也能看到工具.exe执行文件

1.  jps

这个命令和ps -ef |grep java有相似的用处

jps是典型的jvm工具,查看jvm当前运行的项目的进程pid

实践:

运行一个springboot项目

jps -v    展示当前的jvm环境

jps -l   展示当前运行的项目进程pid

2.   jstat -gc 6278  250  20   (进程id/250毫秒打印间隔/打印次数20)   打印gc信息

3.jinfo

实时查看和调整虚拟机的各项参数,虽然使用jps -v 可以查看虚拟机启动时显示指定的参数列表,但是如果想知道

未被显式指定的参数的系统默认值,除了去找资料,就只能使用jinfo-flag选项进行查询了

jinfo 6278(进程pid)展示所有信息

4.jmap

jmap用于生成堆转储快照,如果不使用jmap命令,想要获取java堆转储快照,还有一些暴力的手段:

-XX:+HeapDumpOnOutMemoryError参数,可以让虚拟机在发生OOM的时候自动生成dump文件,便于系统复盘

实战:

使用jps列出系统内的项目

 jps

②查看项目的堆信息

jmap -heap 6872

jmap -histo 6872|more       more用来分页显示

jmap -dump:format=b,file=./a.bin 6872              手动拷贝堆快照到本地,便于后边对转储的快照进行分析

5.jhat

jvm heap analysis tools    jvm内存分析工具,一般搭配jmap -dump来使用,因为jhat分析十分耗内存,先将堆快照转储到本地,节省服务器资源

实战:

①模拟OOM代码:

/**
 * @Auther: jorian
 * @Date: 2019/8/11 23:17
 * @Description:
 */
public class OOMError {
    public static  void main(String []args){
        String name = "xdclass";
        for(int i =0;i<1000000000;i++){
            name+=name;
        }
        System.out.println(name);
    }

}

②配置启动参数,在发生oom异常时自动保存堆快照

-Xms20m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\Administrator\Desktop

③启动程序,因为必然发生oom异常,我们可以发现桌面多出来一个快照文件。

④分析快照

jhat 快照文件名     会启动一个server端port:7000

可以直接在浏览器打开,一般我们拉到最后分析最后的两条

说明:jhat命令已经非常老旧,后面我们会介绍更多的图形界面的内存文件分析工具

6.jstack

当线程出现长时间停顿,我们可以使用jstack生成线程的快照

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

线上程序一般不能使用kill进程pid的方式直接关闭,shutdownHook

jstatck 14665(进程pid)  查看栈快照

7.死锁模拟及使用jstack观察死锁

@SpringBootApplication
public class Jvm01Application {

    public static void main(String[] args) {
        SpringApplication.run(Jvm01Application.class, args);
    }


    /**
     * postconstruct在springboot项目启动的时候执行的方法
     * 在bean加载完但用户线程进来之前执行的方法
     */
    private static Object Lock1 = new Object();
    private static Object Lock2 = new Object();

    @PostConstruct
    public void deadLock(){
        new Thread(()->{
            synchronized (Lock1){
                try {
                    System.out.println(Thread.currentThread().getName()+"得到lock1");
                    Thread.sleep(3000L);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (Lock2){
                    System.out.println(Thread.currentThread().getName()+"得到lock2");
                }
            }
        },"线程1").start();
        new Thread(()->{
            synchronized (Lock2){
                try {
                    System.out.println(Thread.currentThread().getName()+"得到lock2");
                    Thread.sleep(3000L);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                synchronized (Lock1){
                    System.out.println(Thread.currentThread().getName()+"得到lock1");
                }
            }
        },"线程2").start();

    }
}

 

①启动项目后,使用jps获得项目的进程pid

②使用jstack -l pid

可以看到线程死锁的提示:

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值