揭密Java常用性能调优工具的底层实现原理

当JAVA虚拟机出现故障和性能问题时,我们通常会借助一些业界知名的工具来辅助排查问题 。为了能更好的利用这些工具,我们通常需要对这些工具的实现原理有所了解,现有资料在介绍一些性能排查和故障诊断工具时,通常只会围绕这个工具的实现原理展开,例如Eclipse的MAT插件,主要是解读虚拟机的Dump文件 。这篇文章将从虚拟机的角度展开,看看虚拟机到底能提供什么样的静态或运行时数据 。对于HotSpot这款虚拟机来说,能提供的主要数据如下图所示 。

揭密Java常用性能调优工具的底层实现原理

文章插图
 
下面就来简单介绍一下上图中9个部分的数据以及围绕这9部分数据做出来的调优工具 。
1、虚拟机参数、系统变量等如果要查看虚拟机参数或系统变量,可通过如下命令:
// 查看系统配置选项jcmd 5617 VM.flags// 查看虚拟机启动参数jcmd 5617 VM.command_line// 查看系统配置信息jcmd 5617 VM.system_properties许多的虚拟机故障和调优都可通过调整虚拟机参数来达到目地,不过对于一般的Java开发人员来说,这并不是一项简单的工作,需要对虚拟机相关的运行原理有所了解 。
针对虚拟机参数、系统变量等的调优工具有:
(1)VM Options Explorer https://chriswhocodes.com/
(2)HeapDump社区的XXFox
https://opts.console.heapdump.cn/
2、堆转储文件堆转储文件可用来检索整个堆的快照,能够从这个文件中获取到活跃集合、对象的类型和数量,以及对象图的形状和结构等等,堆导出常用的2种方式如下:
(1)通过命令,在发生OOM时导出,可配置参数-XX:+
HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=堆转储文件名
(2)Attach到目标进程后发送dump命令,jmap工具就是这样做的,通过命令jmap -dump:format=b,file=堆转储文件名 pid导出文件 。如文件较大时,可通过添加live参数来有效缩小大小,如果要将堆转储文件转移到其它地方,最好压缩一下,堆转储文件的压缩比例相对较高 。
分析堆转储文件的工具通常都能够给出类实例的数量、类实例的大小等,方便进行堆溢出、频繁GC等问题的排查 。尤其是更多要关注类实例的数量和大小 。假设GC频繁,那么需要重点关注那些类实例占用内存相对较大的;假设GC时间长,需要重点关注实例数量较多的,因为可能活跃的实例较多,标注的时间就会长一些 。
分析堆转储文件的工具有:
(1)Eclipse MAT https://www.eclipse.org/mat/
(2)HeapDump社区的XElephant
https://thread.console.heapdump.cn/
(3)HeapHero https://heaphero.io/
3、线程调用栈通过JDK自带的工具jstack可以导出HotSpot VM的线程栈,这些线程栈对于排查问题非常有帮助,不过导出的线程栈比较原始,拿到这些线程栈后可以做许多的事情,如:
从一次的堆栈信息中,我们可以直接获取以下信息:
  • 是否有很多线程都在等待同一个锁,说明这个系统存在性能瓶颈,导致了锁竞争;
  • 当前线程的总数量,如果线程的总数量有几千上万个,那么大概率是线程泄漏;
  • 每一个线程的调用关系,当前线程在调用哪些函数,从而可看出一些性能比较影响大的一些方法;
  • 每个线程的当前状态,持有哪些锁,在等待哪些锁,是否产生了死锁,当某个锁的等待线程数很多时,很明显这就是系统瓶颈;
  • 大多数线程在干什么,在执行什么代码?
如果指定采样,则从多次采样的堆栈信息中,可以得到以下信息:
  • 线程数不断上涨,可能是线程泄漏;
  • 是否总是存在同一个锁总是有等待的线程,如果有,说明锁是一个性能瓶颈;
  • 一个线程是否长期执行,如果每次打印堆栈某个线程一直处于同样的调用上下文中,那么说明这个线程一直执行这段代码,此时要根据代码逻辑检查,是否合理;
  • 通过多次堆栈信息,结合上火焰图能更容易定位出慢方法;
网络上最常见的通过线程调用栈分析的问题就是CPU使用率高的问题,通过top命令找到占用CPU最高的线程id,然后通过jstack来查看对应线程id的调用栈,不过有些工具可一步到位,例如usefulscripts的show-busy-java-threads脚本,还有Arthas的thread命令等 。
分析线程调用栈的工具有:
(1)HeapDump社区的XSheepdog
https://memory.console.heapdump.cn/
(2)fastThread https://fastthread.io/


推荐阅读