Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

Javaプロファイラの信頼性とバイアスへの付き合い方

 Javaプロファイラの信頼性とバイアスへの付き合い方

JJUG CCC 2024 Spring

Kenji Kazumura

June 16, 2024
Tweet

More Decks by Kenji Kazumura

Other Decks in Programming

Transcript

  1. 3 © 2024 Fujitsu Limited © 2024 Fujitsu Limited 自己紹介

    Jakarta EE 仕様策定委員 MicroProfile ステコミ委員 JCP Executive Committee メンバー Eclipse Foundation ボードディレクター EclipseCon、 JakartaOne、JJUGなどで登壇 3
  2. 5 プロファイラ分類 © 2024 Fujitsu Limited 正確にトレースできるが重い。 gprof、BCIなど。 あまり使われていない? 確率的。

    プロファイラ インストゥルメント (instrumentation) サンプリング 本日の テーマは こちら
  3. 9 アクション可能なプロファイラ © 2024 Fujitsu Limited プロファイラの結果からアクション可能か、が大事 アクション可能な例 プロファイラX 80%

    20% メソッドA メソッドB プロファイラY 70% 30% メソッドA メソッドB 「メソッドAをチューニング」というアクション設定が可能
  4. 10 アクション不可能な例 © 2024 Fujitsu Limited プロファイラX 80% 20% メソッドA

    メソッドB プロファイラY 70% 30% メソッドA メソッドB どちらかが間違っているか、どちらも間違っているか 主な理由は、バイアスと副作用 なので、プロファイラのバイアスを知っておくのが大切
  5. 12 確率的でないサンプリング分布例 © 2024 Fujitsu Limited 10ミリ秒ごとのサンプリング 時間 スレッド1 コンテキストスイッチ

    キャッシュミスが多い 10ms セーフポイントバイアス スレッドダンプ CPU スレッド2 スレッド3 スレッド1 10ms 10ms
  6. 13 セーフポイント © 2024 Fujitsu Limited スレッドの状態が、安全・安定している場所 安全な例 危険な例 スタック

    メモリ Javaヒープ CPU レジスタ スタック メモリ スレッド スレッド オブジェクト オブジェクト 0x20000 0x30000 R4 R1 R3 R2 CPU レジスタ R4 R1 R3 R2
  7. 18 test命令によるセーフポイント実装 © 2024 Fujitsu Limited mov 0x458(%r15),%r11 test %eax,(%r11)

    %r15 スレッド ポインタ 0x458 bad page Java VMが goodpage または badpageを設定 アクセス可能ページ アクセス不可ページ メモリ シグナルハンドラ経由で セーフポイント good page スレッド オブジェクト(C++) 単なるメモリアクセス
  8. 19 セーフポイント設置場所 © 2024 Fujitsu Limited セーフポイント カウントありループ for (int

    i = 0 ; i < m ; ++i) { ・・・ } while (flag == true) { ・・・ } カウントなしループ セーフポイントは 設定されない カウントなしループ メソッド終了 JNI呼出し終了
  9. 20 セーフポイント設置場所 © 2024 Fujitsu Limited -XX:-UseCountedLoopSafepoints で制御可能 最近のJVMではカウントありでも なしでも、セーフポイントが設置

    カウントなしループ メソッド終了 JNI呼出し終了 カウントありループ for (int i = 0 ; i < m ; ++i) { ・・・ } セーフポイントは 設定されないる
  10. 22 プロファイラの実行ステップ © 2024 Fujitsu Limited ハイブリッドプロファイラ サンプリング (PC採取) スタックトレース

    (FP walk) スタックトレース採取 (Javaスレッドダンプ) シンボルと照合し表示 一般的プロファイラ サンプリング (PC採取) スタックトレース (FP walk) シンボルと照合し 表示 Javaプロファイラ スタックトレース採取 (Javaスレッドダンプ) 表示
  11. 23 JavaスレッドダンプAPI © 2024 Fujitsu Limited Java API JVMTI API

    Thread.getAllStackTraces() Thread.getStackTrace() GetStackTrace() GetAllStackTraces() https://docs.oracle.com/javase/jp/21/docs/specs/jvmti.html#stack https://docs.oracle.com/javase/jp/21/docs/api/java.base/java/lang/Thread.html#getStackTrace() https://docs.oracle.com/javase/jp/21/docs/api/java.base/java/lang/Thread.html#getAllStackTraces() いずれもsafepointで実施
  12. 24 AsyncGetCallTrace © 2024 Fujitsu Limited https://bugs.openjdk.org/browse/JDK-8178287 void AsyncGetCallTrace (ASGCT_CallTrace

    *trace, jint depth, void* ucontext) hotspot/share/prims/forte.cpp https://openjdk.org/jeps/435 非公開API 問題もあり 公開APIにする動きあり
  13. 25 Java Flight Recorder サンプリング機能 © 2024 Fujitsu Limited 二種類のサンプリング

    Method Profiling Sample Method Profiling Sample Native CPUで実行中あるいは実行キューにあるJavaコードが対象 以下はサンプリング対象外 JVMにより停止中のスレッド (block/wait/sleepなど) JVMコード実行中のスレッド (GCなど) CPUで実行中あるいは実行キューにあるネイティブコードが対象
  14. 26 JFR仕組み © 2024 Fujitsu Limited スレッドダンプAPIは使っていない セーフポイントバイアスはない (サンプリング時は) JVM(HostSpot)のSR機構を使いスレッドを停止

    Linuxの場合は、SIGUSR2を使用 シンボル照合はセーフポイントバイアスになる -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints で緩和
  15. 29 perfコマンドの実行ステップ © 2024 Fujitsu Limited サンプリング スタックトレース シンボルと照合 perf

    event/PMUを利用 ネイティブ部分はELF。 Java部分は、別途JVMで シンボルマップの作成が必要 jcmd Compiler.perfmap FPベースのstack walk JVMで細工が必要 -XX:+PreserveFramePointer
  16. 30 async-profilerの実行ステップ © 2024 Fujitsu Limited サンプリング スタックトレース シンボルと照合 perf

    event/PMUを利用 ネイティブ部分は、 FPベースのstack walk Java部分は、 AsyncGetCallTrace ネイティブ部分はELF
  17. 32 メソッド・関数の種類 © 2024 Fujitsu Limited Javaコード インタプリタ JITコード 組込みコード

    Java VMコード GCなど ネイティブコード ユーザスペース カーネルスペース
  18. 33 プロファイラ比較 © 2024 Fujitsu Limited VisualVM JFR perf async-

    profiler safepoint bias サンプリング シンボル照合 N/A N/A Javaスタック インタプリタ は不可 組込みコード も可 ネイティブス タック カーネルス タック サポートOS ほぼすべて ほぼすべて Linux Linux/macOS