https://gitee.com/vectorx/NOTE_JVM
https://codechina.csdn.net/qq_35925558/NOTE_JVM
https://github.com/uxiahnan/NOTE_JVM
[toc]
使用上一章命令行工具或组合能帮您获取目标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:商业软件,需要付费。功能强大。
jconsole:从Java5开始,在JDK中自带的java监控和管理控制台。用于对JVM中内存、线程和类等的监控,是一个基于JMX(java management extensions)的GUI性能监控工具。
官方地址:docs.oracle.com/javase/7/docs/technotes/guides/management/jconsole.html
Visual VM是一个功能强大的多合一故障诊断和性能监控的可视化工具。它集成了多个JDK命令行工具,使用Visual VM可用于显示虚拟机进程及进程的配置和环境信息(jps,jinfo),监视应用程序的CPU、GC、堆、方法区及线程的信息(jstat、jstack)等,甚至代替JConsole。在JDK 6 Update 7以后,Visual VM便作为JDK的一部分发布(VisualVM 在JDK/bin目录下)即:它完全免费。
主要功能:
官方地址:visualvm.github.io/index.html
MAT(Memory Analyzer Tool)工具是一款功能强大的Java堆内存分析器。可以用于查找内存泄漏以及查看内存消耗情况。MAT是基于Eclipse开发的,不仅可以单独使用,还可以作为插件的形式嵌入在Eclipse中使用。是一款免费的性能分析工具,使用起来非常方便。
MAT可以分析heap dump文件。在进行内存分析时,只要获得了反映当前设备内存映像的hprof文件,通过MAT打开就可以直观地看到当前的内存信息。一般说来,这些内存信息包含:
MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,例如Sun,HP,SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM的 PHD 堆存储文件等都能被很好的解析。
最吸引人的还是能够快速为开发人员生成内存泄漏报表,方便定位问题和分析问题。虽然MAT有如此强大的功能,但是内存分析也没有简单到一键完成的程度,很多内存问题还是需要我们从MAT展现给我们的信息当中通过经验和直觉来判断才能发现。
官方地址: www.eclipse.org/mat/downloads.php
在运行Java的时候有时候想测试运行时占用内存情况,这时候就需要使用测试工具查看了。在eclipse里面有 Eclipse Memory Analyzer tool(MAT)插件可以测试,而在IDEA中也有这么一个插件,就是JProfiler。JProfiler 是由 ej-technologies 公司开发的一款 Java 应用性能诊断工具。功能强大,但是收费。
特点:
主要功能:
官网地址:www.ej-technologies.com/products/jprofiler/overview.html
数据采集方式:
JProfier数据采集方式分为两种:Sampling(样本采集)和Instrumentation(重构模式)
Instrumentation:这是JProfiler全功能模式。在class加载之前,JProfier把相关功能代码写入到需要分析的class的bytecode中,对正在运行的jvm有一定影响。
Sampling:类似于样本统计,每隔一定时间(5ms)将每个线程栈中方法栈中的信息统计出来。
注:JProfiler本身没有指出数据的采集类型,这里的采集类型是针对方法调用的采集类型。因为JProfiler的绝大多数核心功能都依赖方法调用采集的数据,所以可以直接认为是JProfiler的数据采集类型。
遥感监测 Telemetries
内存视图 Live Memory
Live memory 内存剖析:class/class instance的相关信息。例如对象的个数,大小,对象创建的方法执行栈,对象创建的热点。
堆遍历 heap walker
cpu视图 cpu views
JProfiler 提供不同的方法来记录访问树以优化性能和细节。线程或者线程组以及线程状况可以被所有的视图选择。所有的视图都可以聚集到方法、类、包或J2EE组件等不同层上。
线程视图 threads
JProfiler通过对线程历史的监控判断其运行状态,并监控是否有线程阻塞产生,还能将一个线程所管理的方法以树状形式呈现。对线程剖析。
线程分析主要关心三个方面:
监控和锁 Monitors &Locks
所有线程持有锁的情况以及锁的信息。观察JVM的内部线程并查看状态:
上述工具都必须在服务端项目进程中配置相关的监控参数,然后工具通过远程连接到项目进程,获取相关的数据。这样就会带来一些不便,比如线上环境的网络是隔离的,本地的监控工具根本连不上线上环境。并且类似于Jprofiler这样的商业工具,是需要付费的。
那么有没有一款工具不需要远程连接,也不需要配置监控参数,同时也提供了丰富的性能监控数据呢?
阿里巴巴开源的性能分析神器Arthas应运而生。
Arthas是Alibaba开源的Java诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。Arthas 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:
官方地址:arthas.aliyun.com/doc/quick-start.html
安装方式:如果速度较慢,可以尝试国内的码云Gitee下载。
wget https://io/arthas/arthas-boot.jar wget https://arthas/gitee/io/arthas-boot.jar
Arthas只是一个java程序,所以可以直接用java -jar运行。
除了在命令行查看外,Arthas目前还支持 Web Console。在成功启动连接进程之后就已经自动启动,可以直接访问 http://127.0.0.1:8563/ 访问,页面上的操作模式和控制台完全一样。
基础指令
quit/exit 退出当前 Arthas客户端,其他 Arthas喜户端不受影响 stop/shutdown 关闭 Arthas服务端,所有 Arthas客户端全部退出 help 查看命令帮助信息 cat 打印文件内容,和linux里的cat命令类似 echo 打印参数,和linux里的echo命令类似 grep 匹配查找,和linux里的gep命令类似 tee 复制标隹输入到标准输出和指定的文件,和linux里的tee命令类似 pwd 返回当前的工作目录,和linux命令类似 cs 清空当前屏幕区域 session 查看当前会话的信息 reset 重置增强类,将被 Arthas增强过的类全部还原, Arthas服务端关闭时会重置所有增强过的类 version 输出当前目标Java进程所加载的 Arthas版本号 history 打印命令历史 keymap Arthas快捷键列表及自定义快捷键
jvm相关
dashboard 当前系统的实时数据面板 thread 查看当前JVM的线程堆栈信息 jvm 查看当前JVM的信息 sysprop 查看和修改JVM的系统属性 sysem 查看JVM的环境变量 vmoption 查看和修改JVM里诊断相关的option perfcounter 查看当前JVM的 Perf Counter信息 logger 查看和修改logger getstatic 查看类的静态属性 ognl 执行ognl表达式 mbean 查看 Mbean的信息 heapdump dump java heap,类似jmap命令的 heap dump功能
class/classloader相关
sc 查看JVM已加载的类信息 -d 输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的Classloader等详细信息。如果一个类被多个Classloader所加载,则会出现多次 -E 开启正则表达式匹配,默认为通配符匹配 -f 输出当前类的成员变量信息(需要配合参数-d一起使用) -X 指定输出静态变量时属性的遍历深度,默认为0,即直接使用toString输出 sm 查看已加载类的方法信息 -d 展示每个方法的详细信息 -E 开启正则表达式匹配,默认为通配符匹配 jad 反编译指定已加载类的源码 mc 内存编译器,内存编译.java文件为.class文件 retransform 加载外部的.class文件, retransform到JVM里 redefine 加载外部的.class文件,redefine到JVM里 dump dump已加载类的byte code到特定目录 classloader 查看classloader的继承树,urts,类加载信息,使用classloader去getResource -t 查看classloader的继承树 -l 按类加载实例查看统计信息 -c 用classloader对应的hashcode来查看对应的 Jar urls
monitor/watch/trace相关
monitor 方法执行监控,调用次数、执行时间、失败率 -c 统计周期,默认值为120秒 watch 方法执行观测,能观察到的范围为:返回值、抛出异常、入参,通过编写groovy表达式进行对应变量的查看 -b 在方法调用之前观察(默认关闭) -e 在方法异常之后观察(默认关闭) -s 在方法返回之后观察(默认关闭) -f 在方法结束之后(正常返回和异常返回)观察(默认开启) -x 指定输岀结果的属性遍历深度,默认为0 trace 方法内部调用路径,并输出方法路径上的每个节点上耗时 -n 执行次数限制 stack 输出当前方法被调用的调用路径 tt 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
其他
jobs 列出所有job kill 强制终止任务 fg 将暂停的任务拉到前台执行 bg 将暂停的任务放到后台执行 grep 搜索满足条件的结果 plaintext 将命令的结果去除ANSI颜色 wc 按行统计输出结果 options 查看或设置Arthas全局开关 profiler 使用async-profiler对应用采样,生成火焰图
在Oracle收购Sun之前,Oracle的JRockit虚拟机提供了一款叫做 JRockit Mission Control 的虚拟机诊断工具。
在Oracle收购sun之后,Oracle公司同时拥有了Hotspot和 JRockit 两款虚拟机。根据Oracle对于Java的战略,在今后的发展中,会将JRokit的优秀特性移植到Hotspot上。其中一个重要的改进就是在Sun的JDK中加入了JRockit的支持。
在Oracle JDK 7u40之后,Mission Control这款工具己经绑定在Oracle JDK中发布。
自Java11开始,本节介绍的JFR己经开源。但在之前的Java版本,JFR属于Commercial Feature通过Java虚拟机参数-XX:+UnlockCommercialFeatures 开启。
Java Mission Control(简称JMC) , Java官方提供的性能强劲的工具,是一个用于对 Java应用程序进行管理、监视、概要分析和故障排除的工具套件。它包含一个GUI客户端以及众多用来收集Java虚拟机性能数据的插件如 JMX Console(能够访问用来存放虚拟机齐个于系统运行数据的MXBeans)以及虚拟机内置的高效 profiling 工具 Java Flight Recorder(JFR)。
JMC的另一个优点就是:采用取样,而不是传统的代码植入技术,对应用性能的影响非常非常小,完全可以开着JMC来做压测(唯一影响可能是 full gc 多了)。
官方地址:github.com/JDKMissionControl/jmc
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),即每隔一段时问统计各个线程的栈轨迹。如果在这些抽样取得的栈轨迹中存在一个反复出现的方法,那么我们可以推测该方法是热点方法
Flame Graphs(火焰图)
在追求极致性能的场景下,了解你的程序运行过程中cpu在干什么很重要,火焰图就是一种非常直观的展示CPU在程序整个生命周期过程中时间分配的工具。火焰图对于现代的程序员不应该陌生,这个工具可以非常直观的显示出调用找中的CPU消耗瓶颈。
火焰图,简单通过x轴横条宽度来度量时间指标,y轴代表线程栈的层次。
Tprofiler
案例: 使用JDK自身提供的工具进行JVM调优可以将下 TPS 由2.5提升到20(提升了7倍),并准确 定位系统瓶颈。
系统瓶颈有:应用里释态对象不是太多、有大量的业务线程在频繁创建一些生命周期很长的临时对象,代码里有问题。
那么,如何在海量业务代码里边准确定位这些性能代码?这里使用阿里开源工具 Tprofiler 来定位 这些性能代码,成功解决掉了GC 过于频繁的性能瓶预,并最终在上次优化的基础上将 TPS 再提升了4倍,即提升到100。
官方地址:github.com/alibaba/Tprofiler
Btrace
常见的动态追踪工具有BTrace、HouseHD(该项目己经停止开发)、Greys-Anatomy(国人开发 个人开发者)、Byteman(JBoss出品),注意Java运行时追踪工具井不限干这几种,但是这几个是相对比较常用的。
BTrace是SUN Kenai 云计算开发平台下的一个开源项目,旨在为java提供安全可靠的动态跟踪分析工具。先看一卜日Trace的官方定义:
大概意思是一个 Java 平台的安全的动态追踪工具,可以用来动态地追踪一个运行的 Java 程序。BTrace动态调整目标应用程序的类以注入跟踪代码(“字节码跟踪“)。
YourKit
JProbe
Spring Insight