2

我正在尝试使用异步分析器v.1.8.1 来分析我的应用程序。

JVM 是 openjdk 版本“15-ea”2020-09-15,但同样发生在 openjdk 14.0.1 上。

异步分析器使用以下标志运行:-d 60 -t -i 10000 -o svg

它显示了极其奇怪的结果。在此处输入图像描述我们可以看到硬件线程大部分时间不是在 java.lang.Thread::run 中,而是在一些奇怪的地方。怎么解释?我看到了一个可能的解释,即异步探查器无法正确遍历堆栈跟踪并将这些堆栈跟踪的一部分放在错误的位置。还有其他解释吗?如何修复?

4

1 回答 1

3

我假设您想知道为什么配置文件下面没有 Java 框架clock_gettime

如您所见,堆栈以[unknown_Java]frame 结束。这意味着,线程确实运行了一些 Java 代码,但 async-profiler 无法获取 Java 堆栈跟踪,因为 JVM 无法找到顶部 Java 帧。

发生这种情况是因为System.nanoTime()并且System.currentTimeMillis()是 JVM 内在函数。它们被 JIT 编译为相应 C 函数的直接调用,而无需将线程从状态切换in_javain_native状态。nanoTime这意味着,JVM 在调用or时没有保存指向最后一个 Java 帧的指针currentTimeMillis,因此在异步堆栈遍历期间发现最后一个 Java 帧时存在问题。

不幸的是,async-profiler 对此无能为力。一种可能的解决方法是禁用相应的 JVM 内在函数:

java -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_currentTimeMillis,_nanoTime

顺便说一句,我在你的火焰图中发现奇怪的是clock_gettime调用内核。通常它不应该,因为它是在映射到进程用户空间的vDSOclock_gettime中实现的。原因可能是错误的时钟源/禁用的 vDSO ( 1 , 2 )。

于 2020-10-10T15:39:45.183 回答