万隆的笔记 万隆的笔记
博文索引
笔试面试
  • 在线学站

    • 菜鸟教程 (opens new window)
    • 入门教程 (opens new window)
    • Coursera (opens new window)
  • 在线文档

    • w3school (opens new window)
    • Bootstrap (opens new window)
    • Vue (opens new window)
    • 阿里开发者藏经阁 (opens new window)
  • 在线工具

    • tool 工具集 (opens new window)
    • bejson 工具集 (opens new window)
    • 文档转换 (opens new window)
  • 更多在线资源
  • Changlog
  • Aboutme
GitHub (opens new window)
博文索引
笔试面试
  • 在线学站

    • 菜鸟教程 (opens new window)
    • 入门教程 (opens new window)
    • Coursera (opens new window)
  • 在线文档

    • w3school (opens new window)
    • Bootstrap (opens new window)
    • Vue (opens new window)
    • 阿里开发者藏经阁 (opens new window)
  • 在线工具

    • tool 工具集 (opens new window)
    • bejson 工具集 (opens new window)
    • 文档转换 (opens new window)
  • 更多在线资源
  • Changlog
  • Aboutme
GitHub (opens new window)
  • 大纲

  • 走近Java

  • 内存与垃圾回收

  • 字节码与类加载

  • 性能监控与调优

    • JVM性能监控与调优概述
    • JVM监控及诊断工具-命令行篇
    • JVM监控及诊断工具-GUI篇
      • 概述
      • JConsole
      • Visual VM
      • Java Mission Control
      • Eclipse MAT
      • JProfiler
      • Arthas
      • 其他工具
    • JVM运行时参数
    • GC日志分析
    • 浅堆深堆与支配树
    • QQL语言查询对象信息
  • 监控与性能调优案例

  • Java虚拟机
  • 性能监控与调优
2022-03-14
目录

JVM监控及诊断工具-GUI篇

# JVM监控及诊断工具-GUI篇

# 概述

使用命令行工具或组合能帮您获取目标Java应用性能相关的基础信息,但它们存在下列局限:

  • 无法获取方法级别的分析数据,如方法间的调用关系、各方法的调用次数和调用时间等(这对定位应用性能瓶颈至关重要)。
  • 要求用户登录到目标 Java 应用所在的宿主机上,使用起来不是很方便。
  • 分析数据通过终端输出,结果展示不够直观。

为此,JDK提供了一些内存泄漏的分析工具,如jconsole,jvisualvm等,用于辅助开发人员定位问题,但是这些工具很多时候并不足以满足快速定位的需求。所以这里我们介绍的工具相对多一些、丰富一些。

JDK自带的工具

  • jconsole:JDK自带的可视化监控工具。查看Java应用程序的运行概况、监控堆信息、永久区(或元空间)使用情况、类加载情况等
  • Visual VM:Visual VM是一个工具,它提供了一个可视界面,用于查看Java虚拟机上运行的基于Java技术的应用程序的详细信息。
  • JMC:Java Mission Control,内置Java Flight Recorder。能够以极低的性能开销收集Java虚拟机的性能数据。

第三方工具

  • MAT:MAT(Memory Analyzer Tool)是基于Eclipse的内存分析工具,是一个快速、功能丰富的Java heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗
  • JProfiler:商业软件,需要付费。功能强大。
  • Arthas:阿里巴巴开源的性能分析神器。

推荐:Visual VM、MAT、Arthas、JProfiler。

# JConsole

jconsole (opens new window):从Java 5开始,在JDK中自带的Java监控和管理控制台。用于对JVM中内存、线程和类等的监控,是一个基于JMX(Java Management Extensions)的GUI性能监控工具。

启动:在JDK_HOME/bin目录中找到jconsole可执行文件,双击或者使用命令行执行。

三种连接方式

  • Local:使用JConsole连接一个正在本地系统运行的JVM,并且执行程序的和运行JConsole的需要是同一个用户。JConsole使用文件系统的授权通过RMI连接起链接到平台的MBean的服务器上。这种从本地连接的监控能力只有Sun的JDK具有。
  • Remote:使用下面的URL通过RMI连接器连接到一个JMX代理,service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi。JConsole为建立连接,需要在环境变量中设置mx.remote.credentials来指定用户名和密码,从而进行授权。
  • Advanced:使用一个特殊的URL连接JMX代理。一般情况使用自己定制的连接器而不是RMI提供的连接器来连接JMX代理,或者是一个使用JDK 1.4的实现了JMX和JMX

tuning_jconsole_1.png

# Visual VM

Visual VM (opens new window)是一个功能强大的多合一故障诊断和性能监控的可视化工具。它集成了多个JDK命令行工具,使用Visual VM可用于显示虚拟机进程及进程的配置和环境信息(jps,jinfo),监视应用程序的CPU、GC、堆、方法区及线程的信息(jstat、jstack)等,甚至代替JConsole。在JDK 6 Update 7以后,Visual VM便作为JDK的一部分发布(JDK_HOME/bin目录下)。

插件:Visual VM的一大特点就是支持插件安装,可以通过离线文件安装 (opens new window)(*.nbm),也可以在软件的插件页面在线下载安装。

  • 推荐安装:VisualGC
  • 此外,IDEA的插件市场中也有相关的Visual VM插件,用于开发的手调本地的Visual VM。

两种连接方式

  • 本地连接:监控本地Java进程的CPU、类、线程等
  • 远程连接:略,详细百度。

主要功能:

  • 生成/读取堆内存快照
  • 查看JVM参数和系统属性
  • 查看运行中的虚拟机进程
  • 生成/读取线程快照
  • 程序资源的实时监控
  • JMX代理连接、远程环境监控、CPU分析和内存分析

tuning_visualvm_1.png

# Java Mission Control

Java Mission Control (opens new window)(简称JMC) , Java官方提供的性能强劲的工具,是一个用于对 Java应用程序进行管理、监视、概要分析和故障排除的工具套件。它包含一个GUI客户端以及众多用来收集Java虚拟机性能数据的插件如 JMX Console(能够访问用来存放虚拟机齐个于系统运行数据的MXBeans)以及虚拟机内置的高效 profiling 工具 Java Flight Recorder(JFR)。(Oracle整合JRockit VM的产物,JDK 7u40之后绑定发布)

JMC的另一个优点就是:采用取样,而不是传统的代码植入技术,对应用性能的影响非常非常小,完全可以开着JMC来做压测(唯一影响可能是 Full GC多了)。

tuning_jmc_1.png

Java Flight Recorder

Java Flight Recorder是JMC的其中一个组件,能够以极低的性能开销收集Java虚拟机的性能数据。与其他工具相比,JFR的性能开销很小,在默认配置下平均低于1%。JFR能够直接访问虚拟机内的敌据并且不会影响虚拟机的优化。因此它非常适用于生产环境下满负荷运行的Java程序。

Java Flight Recorder 和 JDK Mission Control共同创建了一个完整的工具链。JDK Mission Control 可对 Java Flight Recorder 连续收集低水平和详细的运行时信息进行高效、详细的分析。

当启用时 JFR将记录运行过程中发生的一系列事件。其中包括Java层面的事件如线程事件、锁事件,以及Java虚拟机内部的事件,如新建对象,垃圾回收和即时编译事件。按照发生时机以及持续时间来划分,JFR的事件共有四种类型,它们分别为以下四种:

  • 瞬时事件(Instant Event) ,用户关心的是它们发生与否,例如异常、线程启动事件。
  • 持续事件(Duration Event) ,用户关心的是它们的持续时间,例如垃圾回收事件。
  • 计时事件(Timed Event) ,是时长超出指定阈值的持续事件。
  • 取样事件(Sample Event),是周期性取样的事件。

取样事件的其中一个常见例子便是方法抽样(Method Sampling),即每隔一段时问统计各个线程的栈轨迹。如果在这些抽样取得的栈轨迹中存在一个反复出现的方法,那么我们可以推测该方法是热点方法

tuning_jmc_2.png

# Eclipse MAT

MAT (opens new window)(Memory Analyzer Tool)工具是一款功能强大的Java堆内存分析器。可以用于查找内存泄漏以及查看内存消耗情况。MAT是基于Eclipse开发的,不仅可以单独使用,还可以作为插件的形式嵌入在Eclipse中使用。是一款免费的性能分析工具,使用起来非常方便。

# 获取堆dump文件

MAT可以专业分析Heap Dump文件。在进行内存分析时,只要获得了反映当前设备内存映像的hprof文件,通过MAT打开就可以直观地看到当前的内存信息。一般说来,这些内存信息包含:

  • 所有的对象信息,包括对象实例、成员变量、存储于栈中的基本类型值和存储于堆中的其他对象的引用值。
  • 所有的类信息,包括classloader、类名称、父类、静态变量等
  • GCRoot到所有的这些对象的引用路径
  • 线程信息,包括线程的调用栈及此线程的线程局部变量(TLS)

说明

  • MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,例如Sun,HP,SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM的 PHD 堆存储文件等都能被很好的解析。
  • 最吸引人的还是能够快速为开发人员生成内存泄漏报表,方便定位问题和分析问题。虽然MAT有如此强大的功能,但是内存分析也没有简单到一键完成的程度,很多内存问题还是需要我们从MAT展现给我们的信息当中通过经验和直觉来判断才能发现。

获取堆dump文件方式

  • jmap命令
  • JVM参数配置(少用):-XX:+HeapDumpOnOutOfMemoryError或 -XX:+HeapDumpBeforeFullGC、 -XX:HeapDumpPath=file_path
  • VisualVM导出堆dump文件

# 分析堆dump文件

MAT软件分析dump文件的几个功能入口:

  • histogram(柱状图):展示了各个类的实例数目以及这些实例的Shallow heap(浅堆)或者Retained heap(深堆)的总和
  • thread overview(线程概览,小齿轮按钮):查看系统中的Java线程、查看局部变量的信息
  • with outgoing references、with incoming references:获得对象互相引用的关系
  • Dominator Tree(支配树):体现对象实例间的支配关系

tuning_mat_1.png

# JProfiler

JProfiler (opens new window) 是由 ej-technologies 公司开发的一款 Java 应用性能诊断工具,功能强大,但是收费。

特点:

  • 使用方便、界面操作友好(简单且强大)
  • 对被分析的应用影响小(提供模板)
  • CPU,Thread,Memory分析功能尤其强大
  • 支持对jdbc,noSql,jsp,servlet,socket等进行分析
  • 支持多种模式(离线,在线)的分析
  • 支持监控本地、远程的JVM
  • 跨平台,拥有多种操作系统的安装版本

主要功能

  • 方法调用:对方法调用的分析可以帮助您了解应用程序正在做什么,并找到提高其性能的方法
  • 内存分配:通过分析堆上对象、引用链和垃圾收集能帮您修复内存泄露问题,优化内存使用
  • 线程和锁:JProfiler提供多种针对线程和锁的分析视图助您发现多线程问题
  • 高级子系统:许多性能问题都发生在更高的语义级别上。例如,对于JDBC调用,您可能希望找出执行最慢的SQL语句。JProfiler支持对这些子系统进行集成分析

IDEA与JProfiler

  • JProfiler中配置IDEA:Setting -> IDE Integrations
  • IDEA集成JProfiler:Plugins -> search : JProfiler

# 数据采集方式

JProfier数据采集方式分为两种:Sampling(样本采集)和Instrumentation(重构模式)

  • Instrumentation:这是JProfiler全功能模式。在class加载之前,JProfier把相关功能代码写入到需要分析的class的bytecode中,对正在运行的jvm有一定影响。
    • 优点:功能强大。在此设置中,调用堆栈信息是准确的。
    • 缺点:若要分析的class较多,则对应用的性能影响较大,CPU开销可能很高(取决于Filter的控制)。因此使用此模式一般配合Filter使用,只对特定的类或包进行分析
  • Sampling(推荐):类似于样本统计,每隔一定时间(5ms)将每个线程栈中方法栈中的信息统计出来。
    • 优点:对CPU的开销非常低,对应用影响小(即使你不配置任何Filter)
    • 缺点:一些数据/特性不能提供(例如:方法的调用次数、执行时间)

注:JProfiler本身没有指出数据的采集类型,这里的采集类型是针对方法调用的采集类型。因为JProfiler的绝大多数核心功能都依赖方法调用采集的数据,所以可以直接认为是JProfiler的数据采集类型。

tuning_jprofiler_1.png

# 菜单功能点概述

  • Telemetrie(遥感监测 ):主要包括进程的内存、对象实例、吞吐量、GC活动、类、线程、CPU负载、自定义遥感监测等一些实时活动监测。

  • Live Memory(内存视图):类以及实例对象的相关信息,例如对象的个数、大小,对象创建的方法执行栈、对象创建热点。

    ● 所有对象 All Objects:显示所有加载的类的列表和在堆上分配的实例数。只有Java 1.5(JVMTI)才会显示此视图。
    ● 记录对象 Record Objects:查看特定时间段对象的分配,并记录分配的调用堆栈。
    ● 分配访问树 Allocation Call Tree:显示一棵请求树或者方法、类、包或对已选择类有带注释的分配信息的J2EE组件。
    ● 分配热点 Allocation Hot Spots:显示一个列表,包括方法、类、包或分配已选类的J2EE组件。你可以标注当前值并且显示差异值。对于每个热点都可以显示它的跟踪记录树。
    ● 类追踪器 Class Tracker:类跟踪视图可以包含任意数量的图表,显示选定的类和包的实例与时间
    
  • Heap Walker(堆遍历 ):能生成dump文件、解析dump文件对堆内存快照进行分析。

  • Cpu Views(CPU视图):JProfiler 提供不同的方法来记录访问树以优化性能和细节。线程或者线程组以及线程状况可以被所有的视图选择。所有的视图都可以聚集到方法、类、包或J2EE组件等不同层上。

    ● 访问树 Call Tree:显示一个积累的自顶向下的树,树中包含所有在JVM中已记录的访问队列。JDBC,JMS和JNDI服务请求都被注释在请求树中。请求树可以根据Servlet和JSP对URL的不同需要进行拆分。
    ● 热点 Hot Spots:显示消耗时间最多的方法的列表。对每个热点都能够显示回溯树。该热点可以按照方法请求,JDBC,JMS和JNDI服务请求以及按照URL请求来进行计算。
    ● 访问图 Call Graph:显示一个从已选方法、类、包或J2EE组件开始的访问队列的图。
    ● 方法统计 Method Statistis:显示一段时间内记录的方法的调用时间细节。
    
  • Threads(线程视图):JProfiler通过对线程历史的监控判断其运行状态,并监控是否有线程阻塞产生,还能将一个线程所管理的方法以树状形式呈现。对线程剖析。

    ● 线程历史 Thread History:显示一个与线程活动和线程状态在一起的活动时间表。
    ● 线程监控 Thread Monitor:显示一个列表,包括所有的活动线程以及它们目前的活动状况。
    ● 线程转储 Thread Dumps:显示所有线程的堆栈跟踪。
    

    提示

    线程分析主要关心三个方面:Web容器的线程最大数(比如:Tomcat的线程容量应该略大于最大并发数);线程阻塞;线程死锁

  • Monitors&locks(监视器&锁 ):所有线程持有锁的情况以及锁的信息。观察JVM的内部线程并查看状态。

    ● 死锁探测图表 Current Locking Graph:显示JVM中的当前死锁图表。
    ● 目前使用的监测器 Current Monitors:显示目前使用的监测器并且包括它们的关联线程。
    ● 锁定历史图表 Locking History Graph:显示记录在JVM中的锁定历史。
    ● 历史检测记录 Monitor History:显示重大的等待事件和阻塞事件的历史记录。
    ● 监控器使用统计 Monitor Usage Statistics:显示分组监测,线程和监测类的统计监测数据
    

tuning_jprofiler_2.png

# Arthas

上述工具都必须在服务端项目进程中配置相关的监控参数,然后工具通过远程连接到项目进程,获取相关的数据。这样就会带来一些不便,比如线上环境的网络是隔离的,本地的监控工具根本连不上线上环境。并且类似于Jprofiler这样的商业工具,是需要付费的。

那么有没有一款工具不需要远程连接,也不需要配置监控参数,同时也提供了丰富的性能监控数据呢?

阿里巴巴开源的性能分析神器Arthas应运而生。

Arthas (opens new window)(阿尔萨斯)是Alibaba开源的Java诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。Arthas 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

# 官方文档

Arthas的文档很齐全,这里列举可能会用到的文档入口,更多内容见官方文档 (opens new window):

  • 快速安装 (opens new window) 、Docker Arthas (opens new window)
  • 快速入门 (opens new window)
  • Web Console (opens new window)
  • 进阶使用 (opens new window)

tuning_arthas_1.png

Web Console:

tuning_arthas_2.png

# 其他工具

Flame Graphs(火焰图):在追求极致性能的场景下,了解你的程序运行过程中cpu在干什么很重要,火焰图就是一种非常直观的展示CPU在程序整个生命周期过程中时间分配的工具。火焰图对于现代的程序员不应该陌生,这个工具可以非常直观的显示出调用找中的CPU消耗瓶颈。网上的关于Java火焰图的讲解大部分来自于Brenden Gregg的博客 (opens new window)。(火焰图,简单通过x轴横条宽度来度量时间指标,y轴代表线程栈的层次。)

Tprofiler (opens new window):案例,使用JDK自身提供的工具进行JVM调优可以将下 TPS 由2.5提升到20(提升了7倍),并准确定位系统瓶颈。

系统瓶颈有:应用里静态对象不是太多、有大量的业务线程在频繁创建一些生命周期很长的临时对象,代码里有问题。

那么,如何在海量业务代码里边准确定位这些性能代码?这里使用阿里开源工具 Tprofiler 来定位 这些性能代码,成功解决掉了GC过于频繁的性能瓶预,并最终在上次优化的基础上将 TPS 再提升了4倍,即提升到100。

  • Tprofiler配置部署、远程操作、 日志阅读都不太复杂,操作还是很简单的。但是其却是能够起到一针见血、立竿见影的效果,帮我们解决了GC过于频繁的性能瓶预。
  • Tprofiler最重要的特性就是能够统计出你指定时间段内 JVM 的 top method,这些 top method 极有可能就是造成你 JVM 性能瓶颈的元凶。这是其他大多数 JVM 调优工具所不具备的,包括 JRockit Mission Control。JRokit 首席开发者 Marcus Hirt 在其私人博客《 Lom Overhead Method Profiling cith Java Mission Control》下的评论中曾明确指出 JRMC 井不支持 TOP 方法的统计。

Btrace:常见的动态追踪工具有BTrace、HouseHD(该项目己经停止开发)、Greys-Anatomy(国人开发,个人开发者)、Byteman(JBoss出品),注意Java运行时追踪工具并不限于这几种,但是这几个是相对比较常用的。BTrace则是SUN Kenai 云计算开发平台下的一个开源项目,旨在为Java提供安全可靠的动态跟踪分析工具。

其他的工具还有YourKit、JProbe、Spring Insight等等。

#JVM性能监控与调优
上次更新: 5/28/2023, 10:57:53 PM
JVM运行时参数

JVM运行时参数→

最近更新
01
2025
01-15
02
Elasticsearch面试题
07-17
03
Elasticsearch进阶
07-16
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式