如何使用JNI + JVMTI捕获JIT的去优化事件,例如“ unstable_if”

问题描述

我非常了解如何捕获JIT的去优化事件。
今天,我阅读了安德烈·潘金(Andrei Pangin)When busy-spining java thread is bound to physical core,can context switch happen by the reason that new branch in code is reached?的精彩回答,然后再考虑一下。

我想用JNI + JVMTI捕获JIT的取消优化事件,例如“ unstable_if,class_check等”,然后将警报发送到我的监视系统或其他任何东西。

有可能吗? 对JVM性能有什么影响?

解决方法

不常见的陷阱和取消优化是HotSpot实现的详细信息。您不会在像JVM TI这样的标准接口中找到它们(该接口是为通用虚拟机而不仅仅是HotSpot设计的)。

正如我的previous answer中所建议的那样,诊断欠优化的一种可能方法是添加-XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation选项并在编译日志中寻找<uncommon_trap>

另一种方法是使用async-profiler跟踪去优化事件。
为此,请使用-e Deoptimization::uncommon_trap_inner
如果使用jfr输出格式,这将向您显示Java代码中发生非优化的位置,以及时间戳。

Deoptimization: async-profiler

自JDK 14起,Flight Recorder(JDK-8216041)也会原生报告取消优化事件。使用JMC中的事件浏览器,您可能会发现所有不常见的陷阱,包括方法名称,字节码索引,取消优化的原因等。

Deoptimization: JFR

以上所有方法的开销都足够小。在生产中使用async-profiler通常没有问题;如果录制设置不是多余的,则JFR也可以。

但是,除非常特殊的情况外,在概要分析非优化中没有太多用处。只要JVM在运行时了解有关该应用程序的更多信息,这对于典型的Java应用程序多次重新编译方法是绝对正常的。听起来可能很奇怪,但是不常见的陷阱是推测优化的常见技术:)如上图所示,即使是HashMap.put之类的基本方法也可能会导致去优化,这很好。

,

在JDK 14(基于OpenJDK)中,您可以使用Event Steaming API以编程方式访问取消优化事件。没有来自本机的API。

import jdk.jfr.consumer.RecordingStream;

RecordingStream s = new RecordingStream();
s.enable("jdk.Deoptimization").withStackTrace();
s.onEvent("jdk.Deoptimization",e -> {
  System.out.println("Time: " + e.getEndTime());
  System.out.println("Reason: " + e.getString("reason"));
  System.out.println("Action: " + e.getString("action"));
  System.out.println("Instruction: "+ e.getString("instruction"));
  System.out.println("Line Number: " + e.getInt("lineNumber"));
  System.out.println("Bytecode Index" + e.getInt("bci"));
  RecordedMethod m = e.getValue("method");
  RecordedStackTrace st = e.getStackTrace();
  RecordedThread t = e.getThread();
  ...
});
s.start();

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...