JVM-20-JVM监控及诊断工具之GUI(二)-MAT与JProfiler

MAT

概述

MAT(Memory Analyzer Tool)工具是一款功能强大的Java堆内存分析器, 可以用于查找内存泄漏以及查看内存消耗情况

MAT是基于Eclipse进行开发的, 不仅可以单独使用, 也可以作为插件的形式嵌入在Eclipse中使用

可以在 官网下载并使用

主要作用就是用来分析Dump文件的

MAT不是一个万能工具, 并不能处理所有类型的堆存储文件, 但是比较主流的如Sun, HP, SAP所采用的的hprof二进制堆存储文件, 已经IBM的PHD堆存储文件等都能被很好的解析

最最重要的功能是可以为开发人员生成内存泄漏报表, 方便定位问题和分析问题

image-20210218133800120

生成Dump文件

file->acquire heap dump -> 选择对应进程即可

MAT介绍

image-20210218135235137

分析Dump文件
histogram

展示各个类的实例数目以及这些实例的shallow heap(浅堆)和retained heap(深堆)的总和

image-20210218135647204

thread overview
  • 查看系统中的java进程
  • 查看局部变量的信息

image-20210218141523633

对象相互引用关系

image-20210218142221798

浅堆与深堆
  • shallow heap(浅堆):

    • 只一个对象所消耗的内存, 在32位系统中, 一个对象引用占4个字节, 一个int类型会占据4个字节, long类型占据8个字节, 每个对象头需要占用8个字节, 根据对快照格式不同, 对象的大小可能回想8字节对齐
    • 以String为例:
      • String类中有两个int变量,占8个字节, 一个对象引用变量占4个字节, 一个对象头占8个字节,总计20字节, 向8字节对齐,最后总大小为24字节(JDK7中)
      • 这24字节为String对象的浅堆大小, 与String的value值无关, 无论value的长度如何, 其浅堆始终为24自己
  • retained heap(深堆)

    • 指对象的保留集中所有的对象的浅堆大小之和
    • 保留集:
      • 对象A的保留集是指A被垃圾回收后, 可以被释放的所有的对象集合(包括对象A本身), 即对象A的保留集可以被认为是只能通过对象A被直接或间接访问到的所有对象的集合, 就是指对象A所持有的对象的集合

    浅堆指对象本身占用的内存, 不包括其内部引用对象的大小, 一个对象的深堆值只能通过该对象访问到的所有对象的浅堆之和,即对象被回收后可以释放的真实空间

对象的实际大小:

对象的实际大小是一个对象所能触及的所有对象的浅堆大小之和, 与深堆并不相同

比如下图中, A.B.C.D.E五个对象, A引用了C.D, B引用看C.E, 那么A的浅堆大小只是A本身, A的实际大小是A.C.D三者之和, A的深堆大小为A.D, 由于C还可以通过B访问到, 所以C并不能算在A的深堆范围之内

image-20210218143925276

支配树

支配树的概念源自于图论

MAT提供了一个称为支配树的对象图, 体现了对象实例间的支配关系, 在对象引用图中所有执行B的路径都经过对象A, 则认为对象A支配对象B, 如果对象A是离对象B最近的一个 支配对象, 则认为对象A为对象B的直接支配者, 支配树是基于对象间的引用图所建立的,具有以下基本特征

  • 对象A的子树(所有被对象A支配的对象集合)表示对象A的保留集即深堆
  • 如果A支配B,那么A的直接支配者也支配B
  • 支配树的边与对象引用图的边不直接对应

image-20210218150149432

JProfiler

概述

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

官网地址

  • 特点:
    • 使用方便,界面操作友好
    • 对被分析的应用小
    • CPU, Thread, Memory分析功能尤其强大
    • 支持对jdbc, noSql, jsp, servlet, socket等进行分析
    • 支持多种模式(在线, 离线)分析
    • 支持监控本地, 远程的JVM
    • 跨平台, 拥有多种操作系统的安装版本
  • 主要功能
    • 方法调用
      • 对方法调用的 分析可以帮助了解应用程序 正在做什么, 并找到提高其性能的方法
    • 内存分配
      • 通过分析堆上对象, 引用链和垃圾收集可以帮助修复内存泄漏问题, 优化内存使用
    • 线程和锁
      • 提供多种针对线程和锁的分析视图帮助发现线程问题
    • 高级子系统
      • 许多性能问题都发生在更高的语义级别上, 例如, 对JDBC的调用, 可以找出执行最慢的SQL语句, JProfiler支持对这些子系统进行集成分析
安装

客户端安装直接去官网下载安装即可

  • JProfiler中配置IDEA(11.0版本需要下面的步骤,11.1.4版本的不需要,只需要在IDEA中安装好插件即可)

Session-> IDE Integrations

image-20210220111908688

选择IDEA

image-20210220113212856

点击Integrate-> Proceed

image-20210220113304031

在C:/User下找到IDEA的一个隐藏目录选择

image-20210220113406425

配置完成

image-20210220113423428

  • IDEA配置启动JProfiler

IDEA中启动JProfiler只需要在Plugins里面搜索JProfiler安装插件

image-20210220111521320

安装完成后, 在settings->tools-> JProfiler 设置启动JProfilr程序路径

image-20210220112814949

IDEA启动选项会出现如下图标, 需要JProfiler检测时, 使用该启动方式启动即可

image-20210220111628926

使用

image-20210220124341573

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

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

一般情况下选择Sampling 模式就足够了,这个也是推荐使用的模式, 其他不需要做任何调整, 使用默认的就可以了

image-20210220130936292

image-20210220131443825

遥感监测

image-20210220131549797

可以点击左侧去查看各个条目详细情况

image-20210220131720018

image-20210220131902525

内存视图
  • All Objects

image-20210220132456347

image-20210220133054164

关注的点:

Size大,数量多->频繁创建的Java对象 -> 死循环, 循环次数过多

Size大,数量不多->存在大的对象-> 读取文件时, byte[] 应该边读边写

存在内存泄漏-> 可以从内存角度查看每次垃圾回收完后的最低点是否成线性关系, 如果是,那么很有可能存在 内存泄漏

之后配合Record Objects进行分析

如果存在一直活跃,且没有被回收过的对象, 那么就很有可能是内存泄漏的原因了

image-20210220134629539

  • Record Objects

image-20210220132645367

  • Allocation Call Tree

image-20210220133404915

  • Allocation Hot Spots

image-20210220133543107

  • Class Tracker

image-20210220135105012

堆遍历

可以生成对快照或者对转储文件

image-20210220135522689

CPU视图

image-20210220140441329

线程视图

image-20210220140837823

主要关三个方面:

  1. web容器的线程最大数, 比如Tomcat的线程容量应该略大于并发数
  2. 线程阻塞
  3. 线程死锁

都可以在History中看到

监视器&锁

image-20210220141121440

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值