JVM虚拟机专题之图形化监控工具-VisualVM

Posted 敲代码的程序狗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM虚拟机专题之图形化监控工具-VisualVM相关的知识,希望对你有一定的参考价值。

VisualVM(All-in-One Java Troubleshooting Tool)是功能最强大的运行监视和故障处理程序之一,它集成了多种性能统计工具的功能,可以替代jstat,jmap,jstack,也可以替代JConsole的使用。VisualVM有一个很大的优点:不需要被监视的程序基于特殊的Agent去运行,因此它的通用性很强,对应用程序实际性能的影响也较小,使得它可以直接应用在生产环境中。

还有一大特点就是支持插件扩展,有了插件的扩展能力,就可以支持更多的功能,例如

  • 显示虚拟机进程以及进程的配置、环境信息(jps、jinfo)。
  • 监视应用程序的处理器、垃圾收集、堆、方法区以及线程的信息(jstat、jstack)。
  • dump以及分析堆转储快照(jmap、jhat)。
  • 方法级的程序运行性能分析,找出被调用最多、运行时间最长的方法。
  • 离线程序快照:收集程序的运行时配置、线程dump、内存dump等信息建立一个快照,可以将快照发送开发者处进行Bug反馈。

打开并连接

程序是在%JAVA_HOME%/bin的目录下,直接双击即可启动客户端,如下图

此监控工具默认的功能较少,我们首先要安装一些插件,方便我们监控使用,点击工具->插件打开插件的安装页面,并选择自己需要的插件下载即可,如下

如果下载不了,请重新设置插件中心配置

根据自己的jdk版本在插件中心页面找到对应版本的地址,然后点击进入,最上面的Catalog URL就是需要的配置中心地址:visualvm.github.io/pluginscent…

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fS7KMpKZ-1651827587183)(https://upload-images.jianshu.io/upload_images/27937678-60b9b3e9d8d4d44a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Up6L9n0i-1651827587184)(https://upload-images.jianshu.io/upload_images/27937678-24894cc02b7c4b36.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

和Jconsole一样,有两种连接方式,一个是本地连接,另一个是远程连接

本地连接:在控制台可以看到本地出现的Java程序,直接双击或者右键打开 即可

远程连接:右键选择JMX连接,输入连接信息IP:端口 点击确定即可(本地节点会下出现一个jmx的图标)前提是Java程序已经添加以下参数启动

-Djava.rmi.server.hostname=127.0.0.1   //远程服务器的IP(本地可访问)
-Dcom.sun.management.imxremote      
-Dcom.sun.management.jmxremote.port=5555  // 远程服务器的端口(随便定一个,用于JMX管理该进程)
-Dcom.sun.management.jmxremote.authenticate=false  // 是否验证(true的话需要配置密码,自行百度吧)
-Dcom.sun.management.jmxremote.ssl=false   //ssl控制

如下两个相同的应用,一个是远程的连接,一个是本地的连接

应用概述

这个概述tab可以查看应用的基本信息,例如java版本,主类,jvm参数(启动参数),系统属性等

监控信息

切换到监控tab 可以看到应用的CPU,堆,元空间,类加载以及线程数的总体变化情况。页面上还有两个按钮执行垃圾回收堆dump,操作按钮可以立即执行full gc(下图堆大小减少)和生存堆快照。

线程分析

切换到线程tab可以看到应用中线程的信息,展现了线程的数量,右上角有个线程Dump的按钮,可以下载当前所有现场的堆栈信息(相当于jstack)。最下面还可以点击每个线程,展示每个线程的信息,如果存在死锁,会以红色字体给出提示,如下图

点击线程Dump按钮,获取的堆栈信息,例如其中的死锁信息,可以直接看到发生死锁的具体位置

性能分析

切换到抽样器tab 可以看到共有CPU和内存两个性能采样器,可以实时的监控对应应用的CPU和内存变化。CPU采样器可以将CPU占用时间定位到具体方法,而内存采样器可以查看当前应用的堆信息,根据页面CPU内存的按钮选择。

CPU采样

下面这个例子让程序占用CPU,看看监控上是什么样子

public class Test2 
    public static void main(String[] args) throws InterruptedException 
        fullCpu();
    
    private static void fullCpu() throws InterruptedException 
        long startTime = 0;
        while (true) 
            startTime = System.currentTimeMillis();
            while (System.currentTimeMillis() - startTime < 8) 
            
            Thread.sleep(2);
        
    

如下图Test2.fullCpu()方法占用了大量的CPU时间,而其他方法就比较空闲。通过这个tab,我们可以很快速方便的定位到应用中最耗资源的方法并解决。(而线程CPU时间,可以看到是根据CPU资源消耗大小对线程的排序)

内存采样

通过内存采样可以实时查看每个类内存占用情况,在应用运行的过程中,visual VM实时更新数据,动态的显示各个class内存占用的大小,同时还可以查看每个线程分配的内存大小。如下图

GC信息

切换到Visual GC的tab,可以看到堆的信息变化的图表,包括Metaspace,老年代,新生代的伊甸区,S0区和S1区的实时动态数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bAxC8ied-1651827587196)(https://upload-images.jianshu.io/upload_images/27937678-68e0fd6620c61533.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

Btrace动态跟踪

Btrace的作用是使在不停机的情况下,通过Hotspot虚拟机的Instrument功能动态的加入调试代码。可以跟踪指定的方法调用,构造函数以及系统内存等信息,我感觉主要的意义在于当程序出现问题时,排查错误的一些必要信息时 (譬如方法参数、返回值等),在开发时并没有打印到日志之中以至于不得不停掉服务时,都可以通过调试增量来加入日志代码以解决问题。

可以说Btrace是检查和解决线上问题的大招,不用重启服务,通过脚本命令执行。

安装Btrace插件之后在对应的应用右键选择 Trace Application 就会进入对应的操作面板,一个代码输入的控制页面。

这个举个例子:已经上线的代码出现空指针,但是对应直接看不出具体原因,需要输出一些额外信息辅助判断,或者需要在日志中输出一些额外信息。

线上代码如下

public class Test2 
    public static int add(int a, int b) 
        return a + b;
    
    public static void main(String[] args) throws InterruptedException 
        while (true)
            int a = (int) Math.round(Math.random() * 100);
            int b = (int) Math.round(Math.random() * 100);
            add(a,b);
            Thread.sleep(2000);
        
    

现在上面的代码已经在线上运行了,但是我现在需要知道a,b两个随机参数的具体值是什么,可以打开Btrace的代码界面,然后填充TracingScript即可,代码如下

/* BTrace Script Template */
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
​
@BTrace
public class TracingScript 
  /* put your code here */
@OnMethod(clazz="/.*Test2", // 监控以Test2结尾的类
           method="add",
           location=@Location(Kind.RETURN))
 public static void func(int a,int b, @Return int result)
   println("开始===============");
   jstack();
   println(strcat("方法参数A:",str(a)));
   println(strcat("方法参数B:",str(b)));
   println(strcat("方法结果:",str(result)));
  

@OnMethod中参数的clazz需要控制的类,method是类中的方法,location中的Kind.RETURN是指方法结束后输出信息以及堆栈信息。想深入了解这三种参数的具体使用方法请自行百度:“Btrace Java”

然后点击Start按钮就会开始执行,看到控制台输出的信息,如图

BTrace的用途很广泛,打印调用堆栈、参数、返回值只是它最基础的使用形式。还可以实现的功能包括监控指定函数的耗时,获取任意行代码信息,脚本定时,获取类的属性等。

在官网上有使用BTrace进行性能监视、定位连接泄漏、内存泄漏、解决多线程竞争问题等的使用案例,有兴趣的读者可以去网上了解相关信息。

官网在此:github.com/btraceio/bt…

最全学习笔记大厂真题+微服务+MySQL+分布式+SSM框架+Java+Redis+数据结构与算法+网络+Linux+Spring全家桶+JVM+高并发+各大学习思维脑图+面试集合

以上是关于JVM虚拟机专题之图形化监控工具-VisualVM的主要内容,如果未能解决你的问题,请参考以下文章

JVM探秘:VisualVM监控远程Java进程

visualVM远程监控JVM

Java虚拟机性能管理神器 - VisualVM 插件安装与更新路径配置

Java 虚拟机原理堆区 | Java VisualVM 工具

JVM性能监测工具——VisualVM

深入理解Java虚拟机-如何利用VisualVM对高并发项目进行性能分析