使用async-profiler进行JVM内存性能微调的指南 | Baeldung


通常Java Profiler采样探测器使用JVM工具接口(JVMTI)设计,并在安全点收集堆栈跟踪。但是这些采样分析器可能会遇到安全点偏差问题
为了全面了解该应用程序,我们需要一个不需要线程位于安全点的采样探查器,并且可以随时收集堆栈跟踪信息以避免安全点偏差问题。
在本教程中,我们将探讨async-profiler及其提供的各种配置技术。
 
async-profiler是用于任何基于HotSpot JVM的 JDK的采样分析器。它具有较低的开销,并且不依赖JVMTI。
通过使用HotSpot JVM提供的AsyncGetCallTrace API来分析Java代码路径,并使用Linux的perf_events来分析本机代码路径,可以避免安全点偏差问题。
换句话说,分析器将Java代码和本机代码路径的调用堆栈进行匹配,以产生准确的结果。
 
首先,我们将基于我们的平台下载最新版本的async-profiler。当前,它仅支持Linux和macOS平台。
下载后,我们可以检查它是否在我们的平台上正常工作:

$ ./profiler.sh --version

 
其次,在Linux平台上使用async-profiler时,我们应确保配置内核以使用所有用户的perf_events捕获调用堆栈:
  • 我们将perf_event_paranoid设置为1,这将允许探查器收集性能信息:

$ sudo sh -c 'echo 1 >/proc/sys/kernel/perf_event_paranoid'

  • 我们将kptr_restrict设置为0以消除对公开内核地址的限制:

$ sudo sh -c 'echo 0 >/proc/sys/kernel/kptr_restrict'

async-profiler可以在macOS平台上自行运行。
 

现在我们的平台已经准备就绪,我们可以构建分析应用程序并使用Java命令运行它:

$ java -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -jar path-to-jar-file

在这里,我们使用-XX:+ UnlockDiagnosticVMOptions -XX:+ DebugNonSafepoints JVM标志启动了我们的分析应用程序,强烈建议您使用JVM标志以获得准确的结果。
现在我们已经准备好分析应用程序了,让我们探索一下async-profiler支持的各种类型的分析。
 
CPU分析
在对CPU进行性能分析时,Async-profiler会收集Java方法的示例堆栈跟踪,包括JVM代码,本机类和内核函数。
让我们使用其PID来分析我们的应用程序:

$ ./profiler.sh -e cpu -d 30 -o summary 66959
Started [cpu] profiling
--- Execution profile --- 
Total samples       : 28
 
Frame buffer usage  : 0.069%

在这里,我们使用-e选项定义了cpu分析事件。然后,我们使用-d <duration>选项收集样本30秒钟。
最后,该-o选项是有用的定义HTML、SVG和树等输出格式。
让我们在对应用程序进行CPU分析时创建HTML输出:

$ ./profiler.sh -e cpu -d 30 -f cpu_profile.html 66959

此外,async-profiler支持开箱即用的火焰图。
让我们使用.svg文件扩展名生成应用程序的CPU配置文件的火焰图:
$ ./profiler.sh -e cpu -d 30 -f cpu_profile.svg 66959

 
内存分配分析
同样,我们无需使用字节码检测等侵入性技术就可以收集内存分配的样本。
async-profiler使用基于TLAB(线程本地分配缓冲区)的采样技术来收集高于TLAB平均大小的堆分配的样本。
通过使用alloc事件,我们可以使探查器能够收集分析应用程序的堆分配:

$ ./profiler.sh -e alloc -d 30 -f alloc_profile.svg 66255

 
挂钟分析
同样,通过使用挂钟配置文件,async-profiler可以对所有线程进行采样,而不论其状态如何(例如运行,休眠或阻塞)。
在对应用程序启动时间中的问题进行故障排除时,这可以派上用场。
通过定义wall事件,我们可以配置探查器以收集所有线程的样本:

$ ./profiler.sh -e wall -t -d 30 -f wall_clock_profile.svg 66959

另外,我们可以使用list选项检查JVM支持的所有分析事件:

$ ./profiler.sh list 66959
Basic events:
  cpu
  alloc
  lock
  wall
  itimer
Java method calls:
  ClassName.methodName

 
IntelliJ IDEA中的async-profiler
IntelliJ IDEA具有与async-profiler集成的功能,可作为Java的性能分析工具。详细点击标题见原文