2015-08-24 63 views
0

我想了解Java飛行記錄器如何採樣使用本機庫(通過我的情況下的JNA)的應用程序。Java飛行記錄器如何採樣本地幀(jni/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秒內完成。我用jdk1.8.0_60使用以下JVM選項運行此測試用例:-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=defaultrecording=true,dumponexit=true,dumponexitpath=jna.jfr

當我打開jna.jfr時,看到轉儲包含一個單個堆棧跟蹤事件。據我瞭解,與大多數分析器不同,JFR在本機代碼運行時不會生成堆棧跟蹤事件。我完全理解JFR不會剖析本地代碼,但我期望堆棧跟蹤事件是通過在java/native代碼邊界處截斷堆棧跟蹤而生成的。

我的設置有問題嗎?或者是預期的行爲?我發現它真的很容易出錯。如果您不仔細驗證樣本計數,那麼很容易相信熱點在Java代碼中,而大部分時間都用在本機代碼中。

它也不可能知道哪裏是最昂貴的本地調用這就是爲什麼你在第一個地方:)

回答

1

飛行記錄器採樣只在Java時發出事件使用一個分析器。如果採樣器碰到本地代碼,那麼可以查看最後一個Java框架,但這不是它的實現方式。

+0

感謝您確認當前的行爲。我假設任何運行本機代碼的用戶都會對這樣的增強感興趣。使Oracle/JFR團隊可以看到此請求的最佳方式是什麼? (我不是Oracle客戶,我只在開發中使用JFR) –

+1

我將更新錯誤數據庫。 –