超厉害 JVM 监控工具:JProfiler、JConsole、JVisualVM,用过都说好!

小七学习网,助您升职加薪,遇问题可联系:客服微信【1601371900】 备注:来自网站

应用发布后,运行的情况怎么样,服务器,数据库资源是否存在浪费的情况? 流量高峰期,我们是否需要增加系统配置,通过什么来判断? 系统卡顿,进程假死,我们通过什么方式来定位问题呢? 这里我介绍几款款不错的…

应用发布后,运行的情况怎么样,服务器,数据库资源是否存在浪费的情况?

流量高峰期,我们是否需要增加系统配置,通过什么来判断?

系统卡顿,进程假死,我们通过什么方式来定位问题呢?

这里我介绍几款款不错的 JVM 监控工具,可以很好的处理以上问题:

  1. JProfiler 详解以及 Demo 举例。
  2. JConsole 详解以及 Demo 举例。
  3. JVisualVM 详解以及 Demo 举例。
  4. jps、jstat、jinfo、jmap、jhat、jstack 指令详细解释以及举例。


常用监控工具和监控指令

刚入行,我接触的是 JConsole 和 JVisualVM 两款工具,这两种最方便,它属于 JDK 自带,在 bin 目录下,直接双击就可以使用。

后来,机缘巧合,看到同事在用 JProfiler,很不错,我爱不释手。

下面,我挨个为大家展示:

  • JProfiler 详解以及 demo 举例
  • JConsole 详解以及 demo 举例
  • JVisualVM 详解以及 demo 举例
  • jps、jstat、jinfo、jmap、jhat、jstack 指令详细解释以及举例

在本文中,我着重讲解 JProfiler,在我看来 JProfiler 的体验还是要比另外两种工具好一些。

JProfiler 详解以及 demo 举例

JProfiler 是一款性能分析工具,可以直接连接运行中的虚拟机,监控 JVM 的性能。

它可以分析 CPU、Thread、Memory 的性能,监控 JDBC、NoSQL、JSP、Servlet、Socket,可以在线分析,也可以离线分析。对平台支持也很友善,支持 Linux、Windows、Mac 等。

它的原理是获取 JVM 分析接口 JVMTI 的数据。

什么是 JVMTI?它是为了虚拟机调试和监控专门提供的一套虚拟机工具接口,本质上是在 JVM 内部进行了许多埋点。通过埋点给外部传递虚拟机的内的运行情况。

如何使用 JProfiler

JProfiler 的安装步骤很简单就不赘述,下载软件后,按照提示,下一步,下一步,然后安装完毕。

点击左上角图标,如下图,链接 JVM:

链接虚拟机

选择需要连接的 JVM,入下图:

选择需要监控的虚拟机

连接成功后 IDEA 工具会有如下提示:

idea 提示

实时监测 Telemetries

整体视图情况,包含内存、垃圾回收、类文件、线程、CPU 使用情况等 5 大块,也是通常人们最关注的地方。连接 JVM 后,可以很直观地查看内存、CPU、GC 等情况。

监控

内存监控详情,选择左侧菜单 Memory,查看内存使用详情。

如图:可以按照堆内存和非堆内存查看。

堆分区

针对堆,我专门编写代码进行了测试,更好的感受堆内存的变化,如下:

我在工程中写了测试程序,循环增加对象。堆内存则出现了明显的增加。

    @RestController    @RequestMapping(\"my/test\")    public class MyTestController {        public static List<User> listTest = new ArrayList<>();        @GetMapping(path =\"/add\")        public Response<Integer> save() throws InterruptedException {            for (int i=0;i<5000000;i++){                System.out.println(\"======\"+i+\"========\");                User user = new User();                user.setId(UUID.randomUUID().toString());                user.setName(\"code\"+i);                listTest.add(user);                Thread.sleep(100);            }            return null;        }    }

程序运行以后,如下图,可以很明显的看到,堆内存增加了。

在这里插入图片描述

左侧菜单:记录的对象 Recorded objects

从时间的维度,记录进程中的对象数量。数量越多也就说明 JVM 压力越大,需要检查程序是否有逻辑问题,有对象没有及时释放。时间久了会导致内存溢出。

内存情况

记录吞吐量 Record Throughput

对象的创建和释放速度展示了 JVM 内,对象创建的速度,例如 每秒创建了多少对象。

对象创建速度越快,就系统内存消耗也就越快。需要及时预警。

内存吞吐量

GC Activity 垃圾回收情况

模拟出现大量垃圾回收。出现大量的垃圾回收的危害,容易给系统造成卡顿,如果频繁出现 Full GC 一定要认真检查原因。否则给用户的体验十分差。

Demo 代码:

    List<UserEntity> listT1 = new ArrayList<>();    int i = 0;    while (true){        System.out.println(\"======\"+i+\"========\");        UserEntityentity = new UserEntity();        entity.setId(UUID.randomUUID().toString());        entity.setUserName(\"code\"+i);        listT1.add(entity);        //Thread.sleep(50);        i++;    }

模拟 GC

类 Classes

虚拟机装载的类的数量,可以帮我们查看类文件的装载情况。

类加载

线程 Threads

监控虚拟机线程使用情况,特别是开启某种秒杀活动,或者大量用户连接,容易导致线程被耗光。

线程使用完毕的危害十分严重,其他链接无法获取到线程,请求将会丢失。

示范代码,模拟开启过量的线程:

    while (flag){        int finalI = i;        Runnable r2 = () -> {            System.out.println(\"开启一个线程\"+ finalI +\";\");            try {                Thread.sleep(500000000);            } catch (InterruptedException e) {                e.printStackTrace();            }        };        new Thread(r2).start();        Thread.sleep(50);        i++;    }

线程监控模拟

CPU 监控

CPU 如果长期达到 90%,则需要考虑,增加系统 CPU 的配置,当 CPU 达到 100%,系统将出现严重的卡顿,无法处理请求。

cpu

内存剖析 Live Memory

单纯看内存使用率,并不能精确定位问题,我们需要查看内存中的对象分布。这个时候,我们可以使用内存视图。

内存视图 Live Memory 可以直观地查看实时的内存使用情况。

例如:当前内存中有哪些对象,当系统出现卡顿等情况,我们可以查看到底是哪些对象占用了大量的内存空间。查看对象的名字,对象的数量,对象的大小。

模拟测试生成大量 User 对象

Demo 代码:

    List<User> list = new ArrayList<>();    int i = 0;    while (true){        System.out.println(\"======\"+i+\"========\");        User user = new User(\"李四\",15,\"男\");        list.add(user);        Thread.sleep(2);        i++;    }

如下图,我们可以清楚地看到内存中的 User 对象,大小占比。一般查看排行靠前的对象,就很好的定位问题了。

内存

也可以从其他维度进行查看,例如从方法、类、包等多个方面查看内存。利于排查问题。

多维度

堆分析 heap walker

堆快照分析,JProfiler 创建一个内部数据库,经过数据库优化,可以生成在堆 walker 中提供视图所需的数据。

如下图,可以看到 User 对象,数量已经非常庞大了。

堆快照

关于 JProfiler 的介绍暂时介绍到这里,因为它的功能远远不止这么点,但我又不能一一全部截图展示。只能靠大家在使用的过程中,细心地摸索。

下面介绍另外两款工具。

JConsole 详解以及 Demo 举例

JConsole 是一种基于 JMX 的可视化监视、管理工具。它主要包含概述、内存、线程、类、VM 概要、MBean,一共 6 个部分。

JMX 是什么?JMX 是一份规范,SUN 公司依据这个规范在 JDK 提供了 JMX 接口。

如何使用 JConsole

点击 JDK/bin 目录下面的 jconsole.exe 即可启动。

使用 JConsole 链接进程:

jconsole

链接成功:首先是概况图,堆内存,线程,类,CPU 占用率。

在这里插入图片描述

单看内存,可以从原始区,年老区,各个维度查看内存使用情况。

在这里插入图片描述

线程部分,可以查看单个线程详情,以及检测线程死锁的情况。

在这里插入图片描述

查看虚拟机的概况

连接名称、运行时间、虚拟机版本、CPU 运行时间、活动线程等等,你所需要看到的概况信息,下图中都是拥有的。

在这里插入图片描述

JVisualVM 详解以及 Demo 举例

JVisualVM 类似于 JConsole,也是 JDK 自带的一款监控工具。JVisualVM 的查看角度稍微丰富一些。

如何使用 JVisualVM

Java 安装目录的 bin 目录内,双击 JVisualVM 启动工具。

然后,连接虚拟机。

在这里插入图片描述

选择您启动的虚拟机,然后链接,就可以看到虚拟机运行的概况了。

在这里插入图片描述

堆 dump

可以查看堆里面具体的实例对象,甚至可以看到堆里面的具体对象的值。

如图:可以看到 user 对象的属性,李四、男、15 岁。

在这里插入图片描述

还可以检测堆对象的数量,以及整体占比大小。如图:

在这里插入图片描述

如下图是查看运行时线程情况。

在这里插入图片描述

jps、jstat、jinfo、jmap、jhat、jstack 指令详细解释以及举例

jps 详解

jps 是 Java 提供的一个显示当前所有 Java 进程 pid 的命令,这个命令主要是用来显示当前系统的进程情况,例如:有哪些进程以及进程 id。

一般使用 jps,目的就是为了查询出进行的 pid,为了方便执行其他指令。

举例说明:查看 Java 进程的 pid 和名称,不需带参数。

jps

在这里插入图片描述

只显示 pid 的方式,加参数 q:

jps -q

jstat 详解

jstat 提供与 JVM 性能相关的统计信息,例如垃圾收集,编译活动。

jstat 最强大的地方,它可以在运行 JVM 时,无需任何先决条件的情况下动态捕获系统指标。

例如:捕捉 GC 信息。

  • -gc:将显示与垃圾收集相关的统计信息

查看进程 25680 的垃圾回收情况,每 2 秒刷新一次,一共刷新 10 次。

jstat -gc -t 25680  2000  10 

效果如图:

在这里插入图片描述

如下是对截图中参数的解释:

  • S0C:幸存者 0 区域的容量
  • S1C:幸存者 1 区域的容量
  • S0U:幸存者 0 区域使用的空间
  • S1U:幸存者 1 区域
  • EC:伊甸园地区容量
  • OC:旧区域容量
  • OU:旧区域的已利用空间
  • MC:元空间区域容量
  • MU:元空间区域使用的空间
  • CCSC:压缩类空间区域的容量
  • CCSU:压缩类空间区域
  • YGC:年轻 GC 事件的数量
  • YGCT:年轻 GC 花费的时间
  • FGC:完全 GC 事件的数量
  • FGCT:完整 GC 时间

jinfo 详解

jinfo 是为了查看虚拟机配置信息,Java 进程运行的 JVM 参数。例如分配的内存多大、堆占多大空间、最小内存、是否开启垃圾回收打印等等。

举例示范:

jinfo -flags 25680

在这里插入图片描述

指令执行完毕返回的内容:

    Attaching to process ID 25680, please wait...    Debugger attached successfully.    Server compiler detected.    JVM version is 25.152-b16    Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=266338304 -XX:MaxHeapSize=4253024256 -XX:MaxNewSize=1417674752 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=88604672 -XX:OldSize=177733632 -XX:+PrintGC -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelGC    Command line:  -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:63181,suspend=y,server=n -javaagent:C:\\Users\\2592\\AppData\\Local\\JetBrains\\IntelliJIdea2020.1\\captureAgent\\debugger-agent.jar -Dfile.encoding=UTF-8

jmap 详解

讲解前,先解释下 dump 的概念。

dump 虚拟机快照文件。dump 文件本质上是一个二进制文件,它记录了虚拟机在某一时刻的运行情况,例如 CPU 使用率、内存分布情况、线程执行情况等等。通过分析 dump 文件,有利于我们快速定位系统出现的问题。

获取 dump 文件,就等于给运行中的虚拟机拍了一个快照。通过分析快照文件,可以获取虚拟机的运行概况。

jmap 如何获取 heap dump 文件

运行如下指令,我们就可以在当前目录获取一个 heap.hprof 文件,也就是堆快照文件。

jmap -dump:format=b,file=heap.hprof 25700

如下图获取的快照文件:

在这里插入图片描述

如何解析快照文件

我们可以使用 JProfiler 打开这个快照文件,然后按照上面的使用教程,一步步分析堆内部的运行情况,定位问题。

在这里插入图片描述

jstack 详解

jstack,可以理解为 CPU 快照指令,可以生成 CPU 的快照文件。这个命令用于生成 JVM 进程当前时刻的线程的调用堆栈,用来定位线程间死锁、锁等待、是不错的选择。

如何使用 jstack

获取 thread dump 文件,采用如下指令,25680 是进程的 pid:

jstack 25680> thread-25680.txt

如下图,我们就可以看到 jstack 生成的快照文件,进而去分析里面的内容了。

在这里插入图片描述

总结

我们在开发日常项目的过程中,往往只顾着编写业务代码,却忽略了项目本身的运行性能。其实,项目在开发完毕后的运维阶段,同样值得关注,软件开发和运维,都是一个持续的过程。

一款软件只有在不断地使用和打磨的过程中,才会越来越好,我们采用合理的监控手段,可以为我们的软件生命周期助力。无论是定位问题,还是事前预警,我介绍的集中监控方式,都可以提供很大的帮助。希望大家一起多多学习,做最好的软件。

小七学习网,助您升职加薪,遇问题可联系:客服微信【1601371900】 备注:来自网站

免责声明: 1、本站信息来自网络,版权争议与本站无关 2、本站所有主题由该帖子作者发表,该帖子作者与本站享有帖子相关版权 3、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和本站的同意 4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责 5、用户所发布的一切软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。 6、您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 7、请支持正版软件、得到更好的正版服务。 8、如有侵权请立即告知本站(邮箱:1099252741@qq.com,备用微信:1099252741),本站将及时予与删除 9、本站所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章和视频仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。