2024-01-22

监控jvm工具:visualVM

为什么要监控jvm

众所周知,jvm(java virtual mechine)是java的精髓

秉持着“一次编码,到处运行”的设计理念,可以说jvm让java在90年代火到了21世纪至今

由c++开发的jvm,它巧妙地设计了java的设计理念——即万物皆对象。并设计了这些对象应该如何存储,如何调用,并通过不断迭代设计让对象的存储和回收,执行更加合理,下图是jvm的发展历程。

[图片上传中...(image.png-d7a15d-1705939070766-0)]

时至今日,jvm这种“虚拟机”设计来运行的语言和生态仍然丰富。比如Kotlin,Groovy,JRuby(也就是说java可能会老,但jvm不会)。

也许开发者未必精通jvm,但对jvm的深入了解可以对开发,排错,调优有非常大的帮助。这里给出最基本的 jvm 入门知识,也是你监控 jvm并期待通过分析jvm来排错调优所必要的基础知识:

  • 堆(Heap):
    • 堆是用于存储对象实例的内存区域。在堆中分配的对象包括通过 new 关键字创建的对象以及数组。
    • 所有线程共享堆,但每个对象都有一个标识它的引用。
  • 栈(Stack):
    • 栈用于存储方法的局部变量、操作数栈、方法返回地址等。每个线程都有自己的栈。
    • 每个方法在执行时都会创建一个栈帧,栈帧包含了该方法的局部变量表、操作数栈、动态链接、方法返回地址等信息。
  • 程序计数器(Program Counter):
    • 程序计数器是每个线程私有的,用于存储当前线程执行的字节码指令的地址或索引。
    • 在多线程环境下,程序计数器用于记录每个线程执行的位置,确保线程切换后能够恢复到正确的执行位置。
  • 本地方法栈(Native Method Stack):
    • 本地方法栈类似于栈,但用于执行本地方法(非 Java 语言编写的方法)。
    • 本地方法栈的实现和栈类似,但用于执行本地代码。
  • 元空间(Metaspace):
    • 元空间是 JDK 8+ 版本中引入的(替代原来的方法区),使用本机内存存储类的元信息,包括类的结构信息、静态变量、方法信息等。

堆内提供垃圾回收,通过监视和清理不再使用的对象,释放内存空间,避免内存泄漏和提高程序性能

VisualVM分析

事实上,由于jvm的不断发展,官方(无论是jdk还是jvm)提供了很多命令和接口编程去帮助开发者监控jvm。

而其中本文详细介绍的VisualVM则是一款官方的,简单可视化的jvm监控工具。

下载安装

官网:https://visualvm.github.io/download.html

Q:如何汉化?

A:请从%JAVA_HOME%/bin下的jvisualvm.exe点击运行,[图片上传失败...(image-8eff0a-1705939107081)]

快速上手

首先启动一个java程序(本地)

你可以查看本地和远程 Java 应用程序的列表

<img src="http://s7mc2e5ie.hd-bkt.clouddn.com/blog/image-20240122210930443.png" alt="image-20240122210930443" style="zoom:33%;" /><img src="http://s7mc2e5ie.hd-bkt.clouddn.com/blog/image-20240122210927004.png" alt="image-20240122210927004" style="zoom:33%;" />

点击该连接,可以看到该java程序的概述页,包括该进程的PID,主机ip,运行主类,jvm参数,jvm版本,JAVA_HOME等

<img src="http://s7mc2e5ie.hd-bkt.clouddn.com/blog/image-20240122211153534.png" alt="image-20240122211153534" style="zoom:33%;" />

点击《监视》页面,可以查看该进程的类,cpu,线程活动,堆占用情况。

在这里可以手动《执行垃圾回收》,jvm会对堆进行垃圾回收,它监视和清理不再使用的对象,释放内存空间,避免内存泄漏,以此提高程序性能。

<img src="http://s7mc2e5ie.hd-bkt.clouddn.com/blog/image-20240122211434876.png" alt="image-20240122211434876" style="zoom:33%;" />

可以看到这个进程设置堆内存为238,026,784B(200多M),最大堆设置为7xxx,堆内存已使用92,573,992B(92M)。

加载的类有15000多个,线程77个。其中活动线程为42个

tips:这里包括了springboot包和项目内部的线程和类。

堆分析

通过点击《堆dump》,可以生成堆的分析文件.hprof,

[图片上传失败...(image-d9f0a2-1705939107081)]

和很多软件和系统(如windows的bat,ps的psd,Android的apk)都会定制他们的格式一样,你不必管它如何打开,只需导入VisualVM即可查看文件内容

线程分析

通过点击《线程》,可以实时监控该进程的线程,如他们的状态,运行时间。

[图片上传失败...(image-33109a-1705939107081)]

如线程之间发生了死锁,它会对你提醒。这里模拟一个死锁程序,如下所示Thread1和Thread0会发生死锁现象(可直接copy运行)

package com.xsrmall.portal;

public class DeadlockDemo {

    public static void main(String[] args) {
        // 创建两个资源对象
        Resource resource1 = new Resource("Resource 1");
        Resource resource2 = new Resource("Resource 2");

        // 创建并启动两个线程
        Thread thread1 = new Thread(() -> {
            try {
                resource1.method1(resource2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                resource2.method2(resource1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        thread1.start();
        thread2.start();
    }

    // 资源类
    static class Resource {
        private String name;

        public Resource(String name) {
            this.name = name;
        }

        // 获取资源1的锁,然后尝试获取资源2的锁
        public synchronized void method1(Resource otherResource) throws InterruptedException {
            System.out.println(name + " is holding " + name);
            Thread.sleep(100); // 模拟执行业务逻辑
            System.out.println(name + " is waiting for " + otherResource.name);
            otherResource.method2(this);
            System.out.println(name + " released " + otherResource.name);
        }

        // 获取资源2的锁,然后尝试获取资源1的锁
        public synchronized void method2(Resource otherResource) throws InterruptedException {
            System.out.println(name + " is holding " + name);
            Thread.sleep(100); // 模拟执行业务逻辑
            System.out.println(name + " is waiting for " + otherResource.name);
            otherResource.method1(this);
            System.out.println(name + " released " + otherResource.name);
        }
    }
}

[图片上传失败...(image-7c7871-1705939107081)]

你可以点击《线程dump》生成线程执行的日志。

[图片上传失败...(image-96d34-1705939107081)]

如上所示,可以看到死锁线程和发生死锁的具体方法,这可以帮助开发者快速定位死锁问题。

tips: idea在执行这里旁边就有转储线程,<img src="http://s7mc2e5ie.hd-bkt.clouddn.com/blog/image-20240122213833377.png" alt="image-20240122213833377" style="zoom:33%;" />[图片上传失败...(image-d76b97-1705939107081)]

抽样器

类似vmWare的快照,它会对此时进程运行的cpu运行情况进行展示

[图片上传失败...(image-4b9491-1705939107081)]

可以看到这个本地的part方法占用了82%的总进程cpu时间。259s。

也可以对内存进行抽样,不再赘述。

Profiler

Profiler可以进行性能分析。目前笔者不需要这个就不看了,待更新。

事实上,VisualVM的很多执行都是去执行提供的类似jmap,jps,jmx规范等jvm/jdk命令

之后会写一篇jdk和jvm提供的监控jvm的命令或java对象。

参考:

https://www.cnblogs.com/liukaifeng/p/10052647.html

https://www.jianshu.com/p/bb4ba6612392

https://heapdump.cn/article/4481245

https://www.cnblogs.com/baby123/p/11551626.html

https://www.liaoxuefeng.com/wiki/1252599548343744/1282385687609378

http://www.oracle.com/technetwork/java/javase/index-138283.html

https://visualvm.github.io/troubleshooting.html?Java_VisualVM

https://www.oracle.com/java/technologies/javase/troubleshooting-javase.html

https://www.51cto.com/article/704419.html

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,825评论 6 546
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,814评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,980评论 0 384
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 64,064评论 1 319
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,779评论 6 414
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 56,109评论 1 330
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 44,099评论 3 450
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,287评论 0 291
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,799评论 1 338
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,515评论 3 361
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,750评论 1 375
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,221评论 5 365
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,933评论 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,327评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,667评论 1 296
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,492评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,703评论 2 380

推荐阅读更多精彩内容