Java Flight Recorder

## インストゥルメンテーション
- JVMの内部データを収集するためにmethodにバイトコードを追加すること。Java言語標準インタフェース「Instrumentation」を利用した製品が各社から提供されている。アプリケーションの状態や動作を変更しないインストゥルメンテーションの例
 - プロファイラ(※本記事のテーマ)、監視エージェント、ロガー、ソースコード簡素化

- プロファイラ
 - JVMに特化した製品（狭義のプロファイラ）、幅広く情報収集できるAPM（Application Performance Monitoring）ソリューション、AI要素が盛り込まれた製品、提供形態も自前型やSaaS等、多岐にわたる。情報取得の仕方（全量 or サンプリング）と処理コストはトレードオフの関係にあり、ユースケースに応じた製品の使い分けが必要。サンプリング方式は処理コストが低いためプロダクション環境で傾向分析用途で利用できるが、障害発生時のピンポイント調査目的では必要な情報が欠損するため利用できない。逆に全量方式は処理コストが高いためプロダクション環境での利用にはむかない。

## プロファイラの例（広義のソリューションを含む）
- Java VisualVM （Oracle JDKにバンドル）
 - 狭義のプロファイラ  + 基本的なJVM解析ツール
- Java Flight Recorder（Oracle JDKにバンドル）
 - BEA社製品「JRockit」の拡張機能「Flight Recorder」がOracle JDKに移植されJMCから利用可能になった。VisualVMよりも高機能でAPMとしてのWebLogic連携機能が充実しているのが特徴。 
- Dynatrace APM
 - Gartner Magic Quadrant for Application Performance Monitoringで右上評価（April 2020）
 - AI、予兆検知、クラウド対応等、カバレッジが広い。
- New Relic APM
 - Magic Quadrant（APM）で好評価（April 2020）
- Amazon CodeGuru Profiler

![SRE.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/572e0d28-4743-3c10-ab86-d6b951b5d65a.gif)


## VisualVM
- JAVA_HOME\bin\jvisualvm.exe
を実行してVisualVMを起動する。
初期表示画面の概要タブでは下記を参照可能

 - JVM引数
 - システムプロパティ

※本資料のVisualVM環境はWindows 10 + Oracle jdk1.8.0_251。
![VisualVM1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/9aedbd17-5788-3521-2c92-33e25709334f.gif)

- 監視タブでは下記を参照可能
 - CPU
 - メモリ
 - クラス
 - スレッド
![VisualVM2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/3473428a-5714-bbb0-4628-ca34e0505747.png)


- 「スレッド」タブでスレッドの状態確認
 - スレッドプールのスレッド利用状況が可視化されるためスレッドチューニング観点で評価ができる。
 ![VisualVM3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/d38709e9-c038-d712-659d-2420a7fc14eb.png)

- 「サンプラ」タブでCPUコストの高い処理を特定する。
 - デフォルト設定の100ミリ秒サンプリング間隔でtps換算のオーバーヘッドは約10%以内であったため性能検証で利用可能なレベル。
しかし、一覧化されるホットメソッドは評価値順に単純ソートされるため実際のアプリケーションの呼び出し階層を踏まえたボトルネック特定は容易でない。
この例ではorg.apache.*に邪魔されてSpring BootのServiceにたどり着くのが容易でない事を示している。
![VisualVM4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/918443a7-cdd1-483a-4fc5-c6840271bd35.png)

- 「サンプラ」タブでメモリコストの高い処理を特定する。
 - 評価値順に単純ソートされるため、プリミティブなクラス、サードパーティー提供のライブラリが上位を占めた時にボトルネック解析が容易ではない。
![VisualVM5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/0fe0dbf8-e254-4f51-8b83-102f74ee5844.png)

- 「プロファイラ」タブでコストの高い処理を特定する。
 - プロファイラ処理のオーバーヘッドが大きい。
性能検証シナリオ次第では処理が止まって見えるレベルとなる。相応の負荷がかかるプロダクション環境での利用は避けたほうが良い。
![VisualVM6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/2b779c67-0a1f-c88b-3af6-6181c29782df.png)

## Java Flight Recorder
- JAVA_HOME\bin\jmc.exeを実行してOracle Java Mission Controlを起動する。プロファイリング対象のJVMを選択して「フライト記録の開始」からJava Flight Recorderを利用する。
※本記事のVisualVM環境はWindows 10 + Oracle jdk1.8.0_251。
![JFR1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/72925c94-5126-49b7-13a1-82606cacf2c5.png)

- 「全般」メニューではCPU、メモリの概況とJVM、システムプロパティが参照可能。
情報収集期間に応じたファイルを参照することで後からの振り返りができることがvisualvmとの大きな違い。情報収集に関するチューニングパラメータが多数あり柔軟な使い方ができるのが大きな特徴。
![JFR2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/64a7f183-8309-4db0-b5fa-56b31cb2811d.png)

- 「メモリ」メニューではメモリの詳細情報が参照可能。
 - visualvmと比較してGC関連の詳細情報が取得可能。
 
![JFR3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/56734ae7-d9dc-17aa-2247-520f8db8d3c1.png)

- 「コード」メニューでは処理のボトルネックに関する詳細情報が参照可能。
 - パッケージ、クラス、メソッド呼び出し関係を踏まえたドリルダウン分析ができるのが大きな特徴。
![JFR4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/bf343e9d-e11b-17e0-08be-7fd553455210.png)

- 呼び出し関係を踏まえたドリルダウン分析の例
どのサービス(Spring BootのService)がホットなのかが簡単にたどれるのが特徴
![JFR5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/a6ba4ed6-461d-cc5d-69bc-36fc26cdd84a.png)

- 「スレッド」メニューでスレッド情報が取得可能。
「ホット・スレッド」タブでホット・メソッドのドリルダウン分析が可能。
![JFR6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/b392a5b5-ad38-2b5d-3b56-13ab09a8886e.png)

- 「システム」メニューでシステムの情報が取得可能。
OSの他のプロセス情報も含めて参照可能。
![JFR7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/36978310-3c04-4aa1-1622-1bf899651cf6.png)

- 「イベント」メニューでJFRのイベント情報が取得可能。
イベントにスタックトレース情報等の詳細情報が紐づいている。
![JFR8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/f1b3dd30-abed-a8d3-f6a0-48535a1cc47a.png)

- 「イベント」メニューでWebLogicイベント情報取得を設定可能。
 - ※WebLogicのWLDF設定をオンにし、JVM引数設定で下記を追加する。
 - -XX:+UnlockCommercialFeatures -XX:+FlightRecorder
![JFR9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/23520109-94c1-4830-831c-88659648985a.png)

- 「WebLogic」メニューでWebLogicイベント情報を参照可能。
※WebLogicで設定したデータソースを利用したJDBCアプリケーションをモニタリングできるのが大きな特徴。実行回数や実行時間でソートして処理のボトルネック解析が可能。リテラル実行もSQL文字列が記録ファイルに残るため機密情報の取り扱いには注意が必要。
![JFR10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325048/b2a0b591-184a-bf24-0145-4c657f52fa89.png)