Java Flight Recorder如何对原生帧进行采样(jni / jna)

时间:2015-08-24 19:52:24

标签: java jvm jvm-hotspot jmc

我试图了解Java Flight Recorder如何对使用本机库的应用程序进行采样(在我的例子中通过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秒才能在我的机器上执行,主机在~30秒内完成。我使用以下JVM选项使用jdk1.8.0_60运行此测试用例:-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=defaultrecording=true,dumponexit=true,dumponexitpath=jna.jfr

当我打开jna.jfr时,我发现转储包含单个堆栈跟踪事件。据我所知,与大多数分析器不同,JFR在本机代码运行时不会生成堆栈跟踪事件。我完全理解JFR不会对本机代码进行概要分析,但我原本期望使用在java /本机代码边界截断的堆栈跟踪生成堆栈跟踪事件。

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

也不可能知道最昂贵的原生呼叫在哪里,这就是你首先使用探查器的原因:)

1 个答案:

答案 0 :(得分:1)

Flight Recorder采样器仅在Java中发出事件。如果采样器遇到本机代码,则可以查看最后一个Java帧,但这不是如何实现的。