首页 > 编程语言 >Java虚拟机的监控及诊断工具(GUI)

Java虚拟机的监控及诊断工具(GUI)

时间:2023-11-07 09:15:05浏览次数:50  
标签:Java 对象 虚拟机 GC 引用 Heap GUI

前面我们总结了Java虚拟机的监控及诊断工具(命令行)相关命令的使用,用命令行虽然说比较方便,但不够直观,要是有图形显示JVM运行的一些情况就好了。eclipse MAT Java Mission Control 是两个使用比较广泛的GUI虚拟机的监控及诊断工具,下面让我们来用用吧。

Eclipse MAT

在命令行那篇,我们已经知道可以用jmap 命令来生成Java虚拟机堆dump文件,那么我们就可以用Eclipse的Memory Analyzer (MAT)工具来解析了。

MAT 支持自己获取dump 文件,它是利用jps命令来列出正在运行的虚拟机进程信息,然后进行选择将要分析的虚拟机进程,如下图所示:

image

我们来选择刚启动的SpringBoot应用,点击对应的选项后,MAT会加载堆快照信息,完成后主界面将会有一个饼状图,列举占据的 Retained heap 最多的几个对象。如下图所示:

image

Retained heap是什么意思,感觉好陌生啊。。不慌,我们来查一下,在Eclipse documentation的Memory Analyzer章节中,介绍了MAT计算内存占用的两种方式,Shallow Heap 和 Retained Heap,简单地了解下:

Shallow Heap

Shallow Heap 是一个对象所占用的内存,不包括它所引用对象的内存,根据32/64位操作系统的不同,该值的计算结果可能有所不同。

Retained Heap

Retained Heap 是一个对象不再被引用时,GC所能回收的总内存,包括对象自身占用的内存,以及仅能通过该对象引用的其他对象所占据的内存。即一些对象需要依赖该对象而存活,GC Roots 不直接引用。下面放一张官方介绍的图解析一下(如下图所示),由于H还被F直接引用,所以E的Retaned Set 只包括E 和 G,不包括H,其他同理。上面饼状图所显示的就是Retained Heap。

image

Mat包含了几种比较重要的视图,Histogram(直方图)和dominator tree(支配树),也提供了线程总览视图。

Histogram(直方图)

image

点击直方图按钮,样式如上图所示。包含各类的对象数量以及Shallow Heap的大小,还统计了Retained Heap的大小,只不过该值为近似值。支持对图中的四个列进行排序,默认是Shallow Heap。

当我们点击具体的类名时,在下面的Inspector面板显示该类的相关信息,比如包名、类名、类加载等信息,如下图所示:
image

dominator tree(支配树)

下面讨论一下支配树视图,说这个之前首先要知道在Java中是通过可达性分析(Reachability Analysis)来判定对象是否存活的。这个算法是基于被称为“GC Roots”的对象作为起点,从这些节点开始向下搜索,所走过的路径被称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链,则这个对象是不可用的。这种概念源自于图论。如下图所示:

image

在Java语言中,可以作为GC Roots的对象有以下几种:

  • 所有Java线程当前活跃的栈帧里指向GC堆里的对象的引用;换句话说,当前所有正在被调用的方法的引用类型的参数/局部变量/临时值。
  • VM的一些静态数据结构里指向GC堆里的对象的引用,例如说HotSpot VM里的Universe里有很多这样的引用。
  • JNI handles,包括global handles和local handles
  • (看情况)所有当前被加载的Java类
  • (看情况)Java类的引用类型静态变量
  • (看情况)Java类的运行时常量池里的引用类型常量(String或Class类型)
  • (看情况)String常量池(StringTable)里的引用

好了,掌握了这么多姿势,来看看支配树的样子,MAT 将默认按照每个对象 Retained heap 的大小排列支配树,如下图所示:

image

从图中可以看出,对象的引用呈链式引用,垃圾回收器回收第一个对象,那么处于链式引用的对象也可以被回收。

定位溢出源

我们还可以利用MAT 提供 的 Path To GC Roots功能来反推出该对象到GC Roots的引用路径,如下图所示:

image

MAT 还提供了Merge Shortest Paths to GC Roots 来显示GC根节点到选中对象的引用路径,如下图所示:

image

image

exclude all phantom/weak/soft etc. reference 意思是排除虚引用、弱引用和软引用,即只剩下强引用,因为除了强引用之外,其他的引用都可以被JVM GC掉,如果一个对象始终无法被GC,就说明有强引用存在,从而导致在GC的过程中一直得不到回收,最终就内存溢出了。

MAT 还提供查询等功能,简直是强大,有空要好好用下,嘻嘻~

Java Mission Control

了解完Mat, 感觉已经很强大,Java 官方有没有提供类似的工具呢?
Java Mission Control(JMC) 和 Java Flight Recorder(飞行记录仪) 是从Java官方提供的一个完整的工具链用来收集JVM底层运行时的信息,可以在线监控JVM的运行情况和进行事后数据分析。

Java Mission Control是Java虚拟机平台的性能检测工具。它包含一个GUI客户端,以及众多众多用来收集JVM性能数据的插件,其中包括Java Flight Recorder。

Java Flight Recorder是一个内置在Oracle JDK中的分析和事件收集框架。它允许开发人员收集关于Java虚拟机(JVM)和Java应用程序行为的详细底层信息。

JMC 是从Java1.7 开始提供的,不过自Java 11开始,不再包含在Java的发行包中,需要单独下载。JFR 在JDK11 开源了,但在之前的 Java 版本,JFR 属于 Commercial Feature,需要通过 -XX:+UnlockCommercialFeatures开启。

启动JMC,然后选择我们要监控的Java的进程,稍等一会就显示出该进程的概览面板,包括当前当前进程的CPU占用率,堆内存情况等信息,注意这些都是实时监控。如下图所示:

image

我们也可以用它来查看当前进程所运行线程的相关情况,包括线程的状态,阻塞次数,CPU总体占用率,是否发生死锁以及分配的内存,挺详细的,如下图所示:

image

JFR

JFR 开启的方式主要有三种,

第一种是在运行目标 Java 程序时添加-XX:StartFlightRecording=参数。关于该参数的配置详情,你可以参考该帮助文档(请在页面中搜索-XX:StartFlightRecording)。

下面的这条命令是在JVM启动后5秒(delay=5s),持续时间为20秒(duration=20s),当收集完后,将数据保存在myrecored.jfr文件中(filename=myrecored.jfr)

$ java -XX:StartFlightRecording=delay=5s,duration=20s,filename=myrecored.jfr,settings=profile MyApp

第二种是通过jcmd来让 JFR 开始收集数据、停止收集数据,或者保存所收集的数据,对应的子命令分别为JFR.start,JFR.stop,以及JFR.dump。

第三种就是我们要操作的,通过JMC的JFR插件来启动。下面是启动参数配置,在该配置选项中,可以配置记录文件的存放位置、持续收集时间等信息:

image

等待收集信息完毕,会出现outline界面,首先映入我们眼帘的是jfr的自动分析结果,CPU暂用率阿等信息,如下图所示:

image

我们发现左边出现了一个outline界面,包括Java应用程序的信息(线程、内存等),JVM内部信息(GC、类加载、TLAB分配等),环境信息(环境变量、当前进程CPU占用情况等)和事件浏览器。如下图所示:

image

查看Java应用程序的信息

点击左侧outline的Java应用程序按钮,在右边会出现当前进程的相关数据总览,包括当前的线程、堆使用情况、CPU占用情况等信息,从下方的图中可以看出发生GC了:

image

当然你可以点击Java应用程序下的小按钮,例如点击内存按钮,显示内存的使用情况:

image

查看GC情况

在虚拟机内部栏,点击垃圾收集按钮,会在右侧显示垃圾回收的情况,包含垃圾回收的次数及暂停时间,当点击具体的一次垃圾收集时,注意在左下角会显示当前垃圾收集的参数,包括类型、开始结束时间等信息。如下图所示:

image

其他的就不再一一介绍了。。贼多~

jvisualvm

Java VisualVM(帮助文档)在JDK11中已被移除,暂时不用了。

参考:


title: Java虚拟机的监控及诊断工具(GUI)
date: 2018-11-22
tags: JVM
categories: [JVM, Tools]

标签:Java,对象,虚拟机,GC,引用,Heap,GUI
From: https://www.cnblogs.com/mingshan/p/17793577.html

相关文章

  • JavaScript string对象(属性,方法)获取图片后缀案例 输入和输出结果转换形式案例
    一、创建string对象varstrOb=newString("abcefg");varstrOb=String("abcefg");varstrOb="abcefg";二、属性length  (字符串长度)varstr='hello';console.log(str.length)//5三、方法1、子字符串位置indexOf(string,[index])str......
  • java base64字符串转换为图片
    javabase64字符串转换为图片实现步骤:base64字符串长这样'"data:image/png;base64,iVBORw0KGgoAAAAN(中间省略好多字符串)AAAABJRU5ErkJggg=='方法一:首先,图片本质上是一种二进制文件,所以创建一张图片,就是创建一个文件,里面写入二进制的数据。#参数avatar接收base64字符串#1......
  • VM 虚拟机挂起之后,或者关闭虚拟机,第二天连接不上 !
    解决方案:1.查看托管是否启动:网卡没有启动可能是没加入托管?2.查看托管是否启动:nmclin如果为disable,说明托管未启用显示为enable,说明是托管是启动了的3.开启托管:nmclinon4.重启:输入:systemctlrestartNetworkManager或者reboot 5.再次尝试xshell连接,重试正常......
  • 虚拟机连接Xshell
    一、检查Linux虚拟机的网络连接模式,选择NAT模式二、在VMwareWorkstationPro里,点击菜单栏上的【编辑】–>【虚拟网络编辑器】,打开下方的虚拟网络编辑器。三、NAT设置四、设置虚拟机的IP、DNS和主机名1、root用户进行如下操作2、登录centos虚拟机五、设置VMnet8在Windows上的IP属......
  • 虚拟机链接网络
    vmware为我们提供了三种网络工作模式,它们分别是:Bridged(桥接模式)NAT(网络地址转换模式)Host-Only(仅主机模式)。打开VMware虚拟机,我们可以在选项栏的“编辑”下的“虚拟网络编辑器”中看到VMnet0(桥接模式)、VMnet1(仅主机模式)、VMnet8(NAT模式),VMnet0表示的是用于桥接模式下的虚拟交换机;VMn......
  • 虚拟机配置网络
    vmware为我们提供了三种网络工作模式,它们分别是:Bridged(桥接模式)NAT(网络地址转换模式)Host-Only(仅主机模式)。打开VMware虚拟机,我们可以在选项栏的“编辑”下的“虚拟网络编辑器”中看到VMnet0(桥接模式)、VMnet1(仅主机模式)、VMnet8(NAT模式),VMnet0表示的是用于桥接模式下的虚拟交换......
  • java基础学习:关键字,标识符
    关键字:属于java语言自己的内容。java已经用了的词:public,static等等标识符: 标识符建议规范驼峰模式,例如:intstudyNumber=4;  开头单词小写,后面的单词首字母大写......
  • 2023_11_06_Java_EE_DAY_01_笔记
    2023_11_06_Java_EE_DAY_01_笔记知识点回顾:JavaseMysqlHtml+css+javascriptVue扩展:ElementPlus作业讲解与分析:知识点讲解:1. 主要核心内容(服务器端开发)a) Javaee/Spring+springMVC+MyBatis/MyBatisPlus/SpringBoot等b) 全栈工程师2. 工具:a) Idea+Mavenb) 等3. ......
  • 每天5道Java面试题(第四天)
    1. Integer和int的区别?1、Integer是int的包装类,int则是java的一种基本数据类型 2、Integer变量必须实例化后才能使用,而int变量不需要 3、Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值。4、Integer的默认值是null,int的默认......
  • Java:SpringBoot实现JDK动态代理和CGLIB动态代理
    (目录)需要代理的对象//接口publicinterfacePayService{voidpay();}//实现publicclassAliPayServiceimplementsPayService{@Overridepublicvoidpay(){System.out.println("AliPayService");}}1.JDK动态代理在JDK动态代......