【jvm系列-12】jvm性能调优篇---GUI工具的基本使用

简介: 【jvm系列-12】jvm性能调优篇---GUI工具的基本使用

一,JVM的诊断监控以及GUI工具的使用

1,GUI工具概述

命令行工具或者组合可以获取到Java应用性能相关的基础信息,但是也存在着一定的局限性,如无法获取到方法级别的数据分析,方法之间的调用关系,调用的次数和调用的时间等,并且使用命令行工具时,需要登录到Java应用所在的虚拟机上,使用起来不是很方便,并且最后通过终端将数据输出展示,不够直观。 因此为了解决命令行工具所带来的问题,则有了GUI工具的诞生。


在图形化工具中,主要分为JDK自带工具和一些第三方工具,JDK自带工具主要有 jConsole,visual VM、JMC 等,第三方工具主要有MAT、JProfiler、Arthas、Btrace。jconsole和visual VM是必须要了解和掌握的,JProfiler和Arthas是属于第三方的,相对于前二者,第三方工具的功能会更多和更强大


2,jConsole

jconsole是用于对jvm内存、线程和类的监控,是一个基于JMX的GUI性能的监控工具。可以在jdk安装目录下面的bin目录下面找到这个jconsole.exe双击进行启动,也可以直接通过在cmd命令中输入jconsole将此工具打开,打开后的界面如下


c37ad4d1f75d4d82b4b22ef634f3cfe3.png


jconsole的连接方式有三种,分别是Local本地连接,Remote远程连接、Advanced连接,使用远程连接的话需要通过一个JMX的代理,并且设置对应的用户名和密码,从而进行授权。而使用本地连接需要注意的是,启动本地代码的用户和启动jconsole的用户得是同一个用户。


这里以本地连接为例,随便运行一段代码,然后在cmd命令行工具中输入jconsole,随后不需要通过jps就可以在本地进程中找到其进程号,然后再双击进去这个进程里面,就可以发现以下的界面,通过下图可以发现,在该界面中,可以实时的监控着堆内存、线程、类、cpu占用率的使用情况。


0a41748a3acc4fe1912baf66437ac700.png


如其内存的监控情况如下,会显示堆内存和非堆内存的信息,堆内存又会分成Eden区和Survivor区,并且每时每秒都对内存进行监控着,其折线图如下,代表的是内存达到一定的量就会触发一次GC


18a6e1a0410a48e1b02ba52d67b37b7b.png


同时也对线程每时每秒的进行监控着,同时这里面还有监测死锁的功能,jstack所对应的GUI

538778721826412e8de06414273cb26e.png



并且可以通过 VM概要 得知一些新生代老年代使用的垃圾收集器的名称,操作系统,jvm供应商等信息



dec7a62e076840bdb69be8849944c631.png

3,Visual Vm(重点)

Visual VM是一个功能强大的多合一的故障诊断和性能监控的可视化工具,集成了多个JDK命令行工具,使用他可以显示虚拟机进程的配置和环境的信息(jps,jinfo),监视应用程序的CPU,GC,堆,方法区以及线程的信息(jstack,jstat)等,甚至可以代替jConsole的使用。


Visual VM不仅自身功能强大,他还有一个特点就是支持插件的扩展,并且插件的安装也很方便。如之前安装过的这个查看这个Visual GC的这个插件。打开这个Visual VM只需要找到jdk的安装目录下的bin目录,找到这个JVisual VM双击即可打开。


e0137571714949f589d510e4944ccdb1.png


又主要分为远程监控和本地监控,远程监控这里暂时不考虑,主要是本地监控,这里会监控着所有的jvm进程。


可以直接在进程右键生成堆Dump的快照文件和线程的快照文件,快照文件就类似于那一刻的一个截图。可以通过查看这个快照文件查看堆栈信息,死锁问题等。

b579ae70abe84ae99eea498bf757db9f.png



除了堆栈之外,还可以对这个CPU和内存进行分析,也可以将此生成对应的快照。


47e0a00adab248acaa3cd697a3443a6b.png


4,JProfiler(强)

在运行java的时候想测试内存的占用情况,这时候就需要用到测试工具。在eclipse里面有MAT插件可以测试,在idea中也有一个插件,就是JProfiler。相对于Visual VM,JProfiler这款工具相对而言更加强大,属于是非JDK自带的工具,因此需要进行付费才能使用。


JProfiler的功能强大,操作也比较友好,对被分析应用的影响小,对CPU,Thread,Memory分析功能强大,同时也支持jdbc,nosql,jsp,serverlet,socket等的操作,也支持监控本地和监控远程的操作。


通过这个JProfiler,可以有以下好处:


在方法调用上分析程序正在做什么,并找到提高其性能的方法;

在内存分配上,通过分析堆对象,引用链等修复内存泄漏的问题,从而优化内存使用;

在线程和锁上,可以提供更多的相关视图来分析和发现多线程的问题;

在高级子系统上,支持堆子系统进行集成分析,如集成JDBC、找出执行最慢的语句。

在本系列第9篇有讲解过这个JProfiler的安装教程,安装完这个插件之后,idea会显示在idea上面,https://blog.csdn.net/zhenghuishengq/article/details/130261481


65bd6781cfe44a159325424a02d7dbb9.png


我这边安装的是11的版本,其激活码为:S-J11-Everyone#553890-77gnvb3w8t9rd#4735


6a86a44b58b342f799af4a1bbfc7b2b2.png


在idea插件中安装完以及本地安装完成之后,需要在这个session集成idea,选择对应安装的idea即可


a9f2eee9a3c84dbcb57aad0a0f51d741.png


在安装完毕之后,点击这个JProfiler这个按钮,就会出现以下的界面,并且控制台会打印一些JProfiler的东西,随后直接点击ok即可。

8c1ee5cecfab485cb6eb6cd14cc65c26.png



然后就会出现以下的画面,会实时的监控堆,CPU,线程,内存,类的总数,GC的时间点以及次数等等相关信息


13eddab25be24e97a331a13191dc76a6.png


接下来再模拟之前的那个死锁的程序

/**
 * @author zhenghuisheng
 * @date : 2023/5/12
 */
public class DeadBlockTest {
    public static void main(String[] args) {
        StringBuilder s1 = new StringBuilder();
        StringBuilder s2= new StringBuilder();
        new Thread(){
            @Override
            public void run() {
                synchronized (s1){
                    s1.append("a");
                    s1.append("b");
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (s2){
                        s2.append("c");
                        s2.append("d");
                    }
                }
            }
        }.start();
        new Thread(){
            @Override
            public void run() {
                synchronized (s2){
                    s1.append("a");
                    s1.append("b");
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (s1){
                        s2.append("c");
                        s2.append("d");
                    }
                }
            }
        }.start();
    }
}

其结果如下,会直接告知有两个线程死锁(真的强这个玩意)

6f74b41e28b74563929fbe60096c95af.png



里面还有很多功能,如通过图形以及图表查看内存泄漏的问题等等,可以安装JProfiler自行测试。


5,Arthas

上面的这几款工具应对日常开发已经足够,接下来再聊一款阿里的开源开发工具Arthas(阿尔萨斯)。改款工具可以不需要通过远程连接,也不需要配置监控参数,就可以对这些数据进行监控。其官方文档如下:arthas.aliyun.com/zh-cn/


4e47720ede97415daae597244932e43e.png


Arthas可以解决的问题如下:


类从哪个jar包加载的,为什么会报这种异常,线上遇到问题时只能加日志重启吗

线上用户数据处理有问题,线下无法重现如何解决

是否有一个全局视角来查看系统的运行状况

有什么办法可以监控到JVM的实时运行状态

怎么快速定位到应用的热点,生成火焰图

其安装方式直接在浏览器输入该地址即可:https://alibaba.github.io/arthas/arthas-boot.jar ,等待片刻将其jar包下载即可,然后将下载的jar包传输到Linux服务器上,然后直接java -jar arthas-boot.jar 运行即可


arthas的基础的相关指令如下:

help: 查看帮助的指令
cat:  打印文件内容,和linux中的目录一样
echo: 打印参数,和linux里的tee相似
pwd:  返回当前目录
session: 查看当前回话信息
history: 打印历史命令

与jvm相关的指令如下:

dashboard:  当前系统的实时数据面板,可以加打印的总次数(-n)和间隔参数(-i)
thread:    查看当前JVM的线程堆栈信息
jvm:        查看当前JVM的信息
sysprop:   查看和修改JVM的系统属性
sysenv:    查看JVM的环境变量
getstatic: 查看类的静态属性
heapdump:  生成堆快照

与class和classLoader相关的信息

sc:          查看JVM已加载类的信息、
sm:         查看已加载类的方法的信息
jad:        反编译已加载类的源码
mc:         .java编译成.class
redifine:   加载外部的.class文件
classloader:查看类的加载器信息

与方法指令相关的信息

monitor:     方法执行监控,如调用次数,执行时间,失败率等
watch:       方法执行数据监测,如异常,返回值,入参等
trace:      方法内部调用路径,输出方法上面每个结点的耗时
stack:      输出当前方法被调用的调用路径

6,总结

在日常开发中,由于本人公司线上使用的是windows服务器,所以界面相对友好,在项目运行中更加的喜欢使用这个JProfiler工具,查看死锁,内存泄漏等问题,当然Arthas相对而言更加的适合在Linux服务器上使用。


除了这些可视化界面之外,还有如JMC、Flame Graphs、Btrace、YourKit、Jprobe、Spring Insight等等,都是可以使用的。


总而言之,没有最好的工具,只有最合适自己使用的开发工具。掌握Jconsole、JVisual VM,JProfiler 就基本能解决很多问题了,如果是线上出现很多疑难杂症,则可以再掌握一门Arthas。


相关文章
|
7天前
|
Arthas 监控 Java
JVM进阶调优系列(9)大厂面试官:内存溢出几种?能否现场演示一下?| 面试就那点事
本文介绍了JVM内存溢出(OOM)的四种类型:堆内存、栈内存、元数据区和直接内存溢出。每种类型通过示例代码演示了如何触发OOM,并分析了其原因。文章还提供了如何使用JVM命令工具(如jmap、jhat、GCeasy、Arthas等)分析和定位内存溢出问题的方法。最后,强调了合理设置JVM参数和及时回收内存的重要性。
|
5天前
|
监控 Java 编译器
Java虚拟机调优实战指南####
本文深入探讨了Java虚拟机(JVM)的调优策略,旨在帮助开发者和系统管理员通过具体、实用的技巧提升Java应用的性能与稳定性。不同于传统摘要的概括性描述,本文摘要将直接列出五大核心调优要点,为读者提供快速预览: 1. **初始堆内存设置**:合理配置-Xms和-Xmx参数,避免频繁的内存分配与回收。 2. **垃圾收集器选择**:根据应用特性选择合适的GC策略,如G1 GC、ZGC等。 3. **线程优化**:调整线程栈大小及并发线程数,平衡资源利用率与响应速度。 4. **JIT编译器优化**:利用-XX:CompileThreshold等参数优化即时编译性能。 5. **监控与诊断工
|
16天前
|
存储 监控 Java
JVM进阶调优系列(8)如何手把手,逐行教她看懂GC日志?| IT男的专属浪漫
本文介绍了如何通过JVM参数打印GC日志,并通过示例代码展示了频繁YGC和FGC的场景。文章首先讲解了常见的GC日志参数,如`-XX:+PrintGCDetails`、`-XX:+PrintGCDateStamps`等,然后通过具体的JVM参数和代码示例,模拟了不同内存分配情况下的GC行为。最后,详细解析了GC日志的内容,帮助读者理解GC的执行过程和GC处理机制。
|
24天前
|
Arthas 监控 数据可视化
JVM进阶调优系列(7)JVM调优监控必备命令、工具集合|实用干货
本文介绍了JVM调优监控命令及其应用,包括JDK自带工具如jps、jinfo、jstat、jstack、jmap、jhat等,以及第三方工具如Arthas、GCeasy、MAT、GCViewer等。通过这些工具,可以有效监控和优化JVM性能,解决内存泄漏、线程死锁等问题,提高系统稳定性。文章还提供了详细的命令示例和应用场景,帮助读者更好地理解和使用这些工具。
|
29天前
|
监控 架构师 Java
JVM进阶调优系列(6)一文详解JVM参数与大厂实战调优模板推荐
本文详述了JVM参数的分类及使用方法,包括标准参数、非标准参数和不稳定参数的定义及其应用场景。特别介绍了JVM调优中的关键参数,如堆内存、垃圾回收器和GC日志等配置,并提供了大厂生产环境中常用的调优模板,帮助开发者优化Java应用程序的性能。
|
1月前
|
存储 监控 算法
JVM调优深度剖析:内存模型、垃圾收集、工具与实战
【10月更文挑战第9天】在Java开发领域,Java虚拟机(JVM)的性能调优是构建高性能、高并发系统不可或缺的一部分。作为一名资深架构师,深入理解JVM的内存模型、垃圾收集机制、调优工具及其实现原理,对于提升系统的整体性能和稳定性至关重要。本文将深入探讨这些内容,并提供针对单机几十万并发系统的JVM调优策略和Java代码示例。
49 2
|
1月前
|
Arthas 监控 Java
JVM知识体系学习七:了解JVM常用命令行参数、GC日志详解、调优三大方面(JVM规划和预调优、优化JVM环境、JVM运行出现的各种问题)、Arthas
这篇文章全面介绍了JVM的命令行参数、GC日志分析以及性能调优的各个方面,包括监控工具使用和实际案例分析。
43 3
|
1月前
|
小程序 Oracle Java
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
这篇文章是关于JVM基础知识的介绍,包括JVM的跨平台和跨语言特性、Class文件格式的详细解析,以及如何使用javap和jclasslib工具来分析Class文件。
41 0
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
|
1月前
|
算法 Java
JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
本文详细介绍了JVM中的GC算法,包括年轻代的复制算法和老年代的标记-整理算法。复制算法适用于年轻代,因其高效且能避免内存碎片;标记-整理算法则用于老年代,虽然效率较低,但能有效解决内存碎片问题。文章还解释了这两种算法的具体过程及其优缺点,并简要提及了其他GC算法。
 JVM进阶调优系列(4)年轻代和老年代采用什么GC算法回收?
|
1月前
|
Java
JVM进阶调优系列(5)CMS回收器通俗演义一文讲透FullGC
本文介绍了JVM中CMS垃圾回收器对Full GC的优化,包括Stop the world的影响、Full GC触发条件、GC过程的四个阶段(初始标记、并发标记、重新标记、并发清理)及并发清理期间的Concurrent mode failure处理,并简述了GC roots的概念及其在GC中的作用。