async-profiler - 低オーバーヘッド JVM プロファイラー チートシート
async-profiler は JVM 用の低オーバーヘッドサンプリングプロファイラーです。従来の Java プロファイラーはセーフポイントでのみサンプリングします。これはセーフポイント付近に座るコードにバイアスをかけ、実ホットパスを隠す可能性があります。async-profiler は AsyncGetCallTrace と perf イベントを使用して任意の場所でサンプリングし、ネイティブコードとカーネルフレームを含め、より正直な描写を提供します。CPU、割り当て、ロック競合などをプロファイルし、フレームグラフまたは JFR をエクスポート。
インストール
| 方法 | 方法 |
|---|
| ダウンロード | プラットフォーム用リリース tarball を入手 |
| 抽出 | tar xzf async-profiler-*.tar.gz |
| 実行 | ./bin/asprof <pid> (新しい) または ./profiler.sh <pid> |
| パーミッション | sysctl kernel.perf_event_paranoid=1 と kernel.kptr_restrict=0 が必要な場合 |
| 確認 | ./bin/asprof --version |
基本的なプロファイリング
| コマンド | 説明 |
|---|
asprof -d 30 -f out.html <pid> | 30 秒プロファイル → フレームグラフ |
asprof -e alloc -d 30 -f alloc.html <pid> | 割り当てプロファイリング |
asprof -e lock -d 30 -f lock.html <pid> | ロック競合 |
asprof -e wall -d 30 -f wall.html <pid> | ウォールクロック (待機含む) |
asprof start <pid> / asprof stop -f out.html <pid> | 手動開始/停止 |
jps | JVM pid を検索 |
イベントタイプ
| イベント | 測定 |
|---|
cpu | CPU 時間 (デフォルト) |
alloc | スタック別ヒープ割り当て |
lock | ロック/モニター競合 |
wall | ブロック時間を含むウォールクロック |
itimer | perf が利用できないときのフォールバック |
cache-misses、page-faults | ハードウェア/ソフトウェア perf イベント |
# アプリがどこで実際にウォールクロック時間を費やすか (IO 待機含む)?
./bin/asprof -e wall -t -d 30 -f wall.html <pid>
出力フォーマット
| フラグ | 生成 |
|---|
-f out.html | インタラクティブなフレームグラフ |
-o collapsed | 折りたたまれたスタック (FlameGraph ツール向け) |
-o tree | コール・ツリー |
-o flat | フラットなホット・メソッドリスト |
-f out.jfr | JFR 記録 (JMC で開く) |
-t | スレッド別に分割 |
エージェントで起動
# JVM 起動からプロファイル (warmup をキャプチャ)
java -agentpath:/path/libasyncProfiler.so=start,event=cpu,file=profile.html \
-jar app.jar
| エージェントオプション | 目的 |
|---|
start | 直ちに開始 |
event=cpu|alloc|lock | サンプリング対象 |
file=NAME | 出力パス |
interval=10ms | サンプリング間隔 |
jfr | JFR フォーマット放出 |
フレームグラフを読む
| 機能 | 意味 |
|---|
| 幅 | サンプルシェア (時間) — より広いほどホッター |
| 高さ | スタック深さ、コストではない |
| 色 | Java (緑)、ネイティブ (黄色ぽい)、カーネル (オレンジ) |
| クリック | サブツリーにズーム |
| 検索 | マッチングフレームをハイライト |
ワイドプラトーを探してください — 大きな水平シェアを消費する 1 つのフレームがホットスポット。混合 Java/ネイティブ/カーネルフレームはセーフポイントバイアスプロファイラーが隠す正確なもの。
一般的なワークフロー
# 1) 実行中のサービスの CPU ホットスポット
./bin/asprof -d 60 -f cpu.html $(jps | grep MyApp | cut -d' ' -f1)
# 2) GC 圧力の追跡 — 最も割り当てるのは誰?
./bin/asprof -e alloc -d 60 -f alloc.html <pid>
# 3) スレッドは遊んでいるが遅延は高い → ウォールクロック
./bin/asprof -e wall -t -d 30 -f wall.html <pid>
# 4) 共有リソースの競合
./bin/asprof -e lock -d 30 -f lock.html <pid>
async-profiler 対 代替案
| 側面 | async-profiler | JFR | VisualVM |
|---|
| セーフポイントバイアス | 回避 | 削減 | 存在 |
| ネイティブ/カーネルフレーム | はい | 限定的 | いいえ |
| オーバーヘッド | 非常に低い | 低い | より高い |
| 割り当てプロファイリング | はい | はい | 基本的 |
| 最適用途 | 正確な JVM ホットスポット | 組み込み継続記録 | クイック GUI 検査 |
ネイティブコード用の perf + FlameGraph の JVM 対応。
リソース