java - Java Flight Recorder 如何对 native 帧进行采样 (jni/jna)

标签 java jvm jvm-hotspot jmc

我试图了解 Java Flight Recorder 如何对使用 native 库的应用程序进行采样(在我的例子中通过 JNA)。

让我们编写一个测试用例,大部分时间都花在祖国:

public class Main {

    interface MyLib extends Library {
        long doStuff(long seed);
    }

    public static void main(String[] args) {
        MyLib myLib = (MyLib) Native.loadLibrary("mylib", MyLib.class);

        LongStream.range(0, 10)
                .map(myLib::doStuff)
                .forEach(System.out::println);
    }
}

doStuff 是一个缓慢的、受 CPU 限制的函数

int64_t doStuff(int64_t acc) {
    for (int i = 0; i < 1<<30; i++) { acc += i; }
    return acc;
}

doStuff 在我的机器上执行需要大约 2 秒,而 main 在大约 30 秒内完成。我使用以下 JVM 选项使用 jdk1.8.0_60 运行此测试用例:-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=defaultrecording=true,dumponexit=true,dumponexitpath=jna.jfr.

当我打开jna.jfr时,我看到转储包含一个单个堆栈跟踪事件。据我了解,与大多数探查器不同,JFR 在 native 代码运行时不会生成堆栈跟踪事件。我完全理解 JFR 不会分析 native 代码,但我预计堆栈跟踪事件是通过在 java/ native 代码边界截断的堆栈跟踪生成的。

我的设置有问题还是预期的行为?我发现它真的很容易出错。如果您不仔细验证样本数量,很容易相信热点在 Java 代码中,而大部分时间都花在 native 代码中。

也不可能知道最昂贵的 native 调用在哪里,这就是您首先使用分析器的原因:)

最佳答案

飞行记录器采样器仅在 Java 中发出事件。如果采样器命中 native 代码,则可以查看最后一个 Java 帧,但这不是它的实现方式。

关于java - Java Flight Recorder 如何对 native 帧进行采样 (jni/jna),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32190618/

相关文章:

java - JVM 8 退出代码 -559038737 (0xDEADBEEF)

java - 将列表从 JSP 发送回 servlet

java - jSSC 未检测到 Com 端口

java - 64 位 Linux 上的 JVM、Tomcat

scala - Future[Future[T]] 到 Future[T] 在另一个 Future.map 中而不使用 Await?

java - 了解 Hotspot JVM 进程的内部碎片属性

java - 为特定方法/类禁用 Java JIT?

java - 无法弄清楚我的基本 Android 应用程序的代码有什么问题

java - 是否可以使用 "sealed methods"改进密封类?

java - 浪费内存来加速jvm