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


(3)生成火焰图的async-profiler
https://Github.com/jvm-profiling-tools/async-profiler
async-profiler直接抓取的是C/C++栈的调用栈,如果要生成Java调用栈的火焰图,可通过jstack工具导出Java调用栈,然后整理成collapsed格式,利用async-profiler生成火焰图即可 。
4、日志日志是出了系统问题第一手的排查资料,尤其是开发人员自己记录的应用日志 。
(1)业务日志
一般是应用的开发者根据不同的业务需求落日志,最终会通过大数据采集后进行存储,方便以报表的方式展现,也能辅助运营人员对业务做出优化 。这一类数据对系统问题排查的帮助不大,可直接忽略 。
(2)应用日志
应用可能会采集起来进行人工排查或监控 。大多数开发人员在查找系统问题时,也应该重点关注这些系统日志,因为它包含应用程序编写的各种错误消息,警告或其他事件 。这些消息可以提供与特定用例相关的详细信息 。如

  • 用例中发生的异常的堆栈跟踪 。有关外部系统响应时间较慢的警告消息 。用例被触发或完成的信息 。
(3)系统日志
GC日志、Crash文件等属于JVM相关的系统日志 。这里我们只介绍一下GC日志,因为它比较重要,记录的信息比较全面 。需要配置GC参数来开启,如下:
Java 8版本:-XX:+PrintGC(或-verbose:gc) -XX:+PrintGCDetAIls -XX:+PrintGCDateStamps -Xloggc:日志名称
Java 9及9+版本:-Xlog:gc*:file=日志名称
GC日志能够给出回收前后堆中各个代的大小、总堆的大小、GC发生的原因及GC所花费的时间等,连续监控GC日志能够得到GC发生的频次及内存分配率等 。好多人有的问题就是,想要知道GC触发的原因,目前只能通过GC日志来查看,所以建议配置GC日志 。
由于GC日志含有的数据指标多,而且日志没有一个标准的格式,所以要借助一些专业的日志解析工具查看,典型的分析工具如下:
(1)开源GCViewer
https://github.com/chewiebug/GCViewer
(2)GCeasy https://gceasy.io
(3)商用工具Censum
https://www.jclarity.com/pricing/censum-as-a-service-enterprise/
5、PerfData对于HotSpot VM来说,会将一些统计信息写到一个叫PerfData的共享文件中,默认路径为/tmp/hsperfdata_<user>/ 。在我的本机上看一下/tmp/hsperfdata_<user>/目录下的内容:
揭密Java常用性能调优工具的底层实现原理

文章插图
 
其中的名称文件是pid,我们可以从/tmp/hsperfdata_<user>/<pid>这个特定的文件中获取相关数据 。
JDK自带的工具jps就是直接读取这个目录下的文件名来列出所有的Java进程号 。正常情况下当JVM进程退出的时候会自动删除,但是当执行kill -9命令时,由于JVM不能捕获这种信号,虽然JVM进程不存在了,但是这个文件还是存在的 。这个文件不是一直存在的,当再次有JVM进程启动时会自动删除这些无用的文件 。jps在读取/tmp/hsperfdata_<user>/路径下的文件名称时,也会通过attach的方式判断这个进程是否存活,这样就能保证读取出的是存活的进程 。
JDK自带的工具jstat也是通过读取PerfData中特定的文件内容来实现的 。由于PerfData文件是通过mmap的方式映射到了内存里,而jstat是直接通过DirectByteBuffer的方式从PerfData里读取的,所以只要内存里的值变了,那我们从jstat看到的值就会发生变化,内存里的值什么时候变,取决于
-XX:PerfDataSamplingInterval这个参数,默认是50ms,也就是说50ms更新一次值,基本上可以认为是实时的了 。基于PerfData实现的jstat,因为垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,所以只需直接读取即可 。
jstat在读取相关内容时,需要知道键值对,查看键值对的方式如下:
 
jstat -J-Djstat.showUnsupported=true -snap 4726
 
或者直接查看
jdk/src/share/classes/sun/tools/jstat/resources/jstat_options文件,其中给出了timestamp、class、compiler、gc、gccapacity、gccause、gcnew、gcnewcapacity、gcold、gcoldcapacity、gcmetacapacity、gcutil、printcompilation这几个大类中的相关信息 。
相关工具有:
(1)JDK自带的jps、jstat
(2)vjtools中的vjtop
https://github.com/vipshop/vjtools/tree/master/vjtop
6、JMXJVM是一个成熟的执行平台,它为运行中的应用程序注入、监控和可观测性提供了很多技术选择,而JMX(Java Management Extensions)就是一种,通过JMX可以实现对类加载监控、内存监控、线程监控,以及获取Java应用本地JVM内存、GC、线程、Class、堆栈、系统数据等 。另外,还可以用作日志级别的动态修改,比如 log4j 就支持 JMX 方式动态修改线上服务的日志级别 。最主要的还是被用来做各种监控工具,比如Spring Boot Actuator、JConsole、VisualVM 等 。


推荐阅读