Java プロファイリングとは、メソッド実行、スレッド実行、オブジェクト作成、ガーベッジコレクションなどのさまざまな JVM レベルのパラメータを監視する処理である。スレッド ダンプは、特定のプロセスの一部であるすべてのスレッドの状態のスナップショットです。
Linux で ‘jps’ コマンド (JVM process status tool) を実行すると、ターゲット システム上のインスツルメンテッド HotSpot Java 仮想マシン (JVM) とその対応するプロセス ID を取得することができます。
Figure 1- JVMs and their pid.LIST (JVMプロセスステータスコピー).
‘jps -l’ コマンドは、アプリケーションのメインクラスのフルパッケージ名またはアプリケーションのJARファイルへのフルパス名を出力します。 以下は、スレッドダンプをキャプチャするために発行する必要があるコマンドです:jstack <pid>. ここでpidは、スレッドダンプをキャプチャするアプリケーションのプロセスIDです。 このため、コンソールで「jstack 13626」を実行すると、図のようなスレッドダンプのログが出力されます。
Builtin Profiling tools and their implementation
Java VisualVM.X のような JVM プロファイルを行うビルドインのツールは、この他にさまざまなものが存在しますが、ここでは Java プロファイルツールについて説明します。Honest Profiler、Async Profiler、Java Mission Controller
これらのプロファイラーを深く理解する前に、「安全点」の概念を知っておく必要があります。 JVMは、ガーベッジコレクションやJITコンパイルなど、多くのことを内部で処理しています。 そのため、JVMはアプリケーションの外で、自分自身のためにいくつかのことを解決する時間も必要です。 JVMができることのいくつかは、セーフポイント(GCを含む)を含むかもしれません。 セーフ・ポイントの間、Javaコードを実行しているすべてのスレッドは、JVMがその仕事をするために中断されます。 そのため、一部のプロファイラーは、指定されたスレッドにコールバックを与え、それらのスレッドはそのコールバックに応答するためにセーフポイントにあるべきという、これらのセーフポイント問題に悩まされています。 ASGTを使用するには、まずJVMTIエージェントを作成します。Java Virtual Machine Tool Interface(JVMTI)は、ソフトウェア開発者が、Javaプログラミング言語アプリケーションを監視および制御できるソフトウェアエージェントを作成できるプログラミングインターフェイスを提供します。その信号は実行中のJVMに向けられ、その実行中のスレッドの1つが中断され、我々のシグナルハンドラにコールバックされます。中断されたスレッドがあなたのシグナルハンドラで実行されていることを確認し、AGCTを呼び出します。正直プロファイラは、プロファイリングを行うためにこのASGTを使用します。 C++のJVMTIエージェントは、JVMTIエージェントが接続されたアプリケーションに関するすべてのプロファイリング情報を含むファイルを書き出す。第2部は、以前に生成されたこのログに基づいてプロファイルをレンダリングするJavaアプリケーションである。 AsyncGetCallTrace(ASGCT_CallTrace *trace,jint depth,void* ucontext) .We should pass a pointer to ASGT call trace to this method.
この方法の問題は、典型的な Java スタック トレースとはわずかに異なるデータを取得することです。 プロファイラーはそれを処理し、ソース コード内の行にマッピングしなければ役に立ちません。
Async プロファイラーは、実行中の JVM プロセスにネイティブ Java エージェントをアタッチして動作し、HotSpot 固有の API を使用してスタック トレースのサンプルを収集する、オーバーヘッドの小さなサンプリング プロファイラーです。 一般的なアプローチは、perf_events によって生成されたコールスタックを受け取り、AsyncGetCallTrace によって生成されたコールスタックと照合し、Java とネイティブコードの両方の正確なプロファイルを生成することです。 perf_events APIを使用してCPUサンプリングをメモリバッファに設定し、サンプリングが発生したときに配信されるシグナルを要求しています。 シグナルハンドラはAGCTを呼び出し、AGCTによって捕捉されたJavaスタックと、perf_eventsによって捕捉されたネイティブ+カーネルスタックの2つのスタックを一緒にマージします。 Java Mission Controller(JMC) は、各 JVM 内の特定のスレッドとその CPU 消費率の詳細なレポートを効率的に提供します。Java Mission Control は、JVM 内で動作する内蔵 VM とアプリケーションの計測を統合する MBean サーバーを持つ JVM の JMX エージェントと対話することによって動作します。 これは、既存のフックを使うので、ツールのオーバーヘッドコストを本当に低くすることができるという重要な利点がある。 Oracleの発表によると、このオーバーヘッドは通常1%未満です。また、このツールを動作させるために、既存のVMにインストールしたり、アタッチしたりする必要はありません。 Flight recorderの場合、いくつかのフラグを有効にする必要がありますが、インストールするものはありません。 JMCは、実行中のJVMを含むGUIを出力します。プロファイルするJVMプロセスを選択し、制限時間を指定して記録を開始します。
別のよくある代替案は Linux perf の使用で、Java は直接サポートしていませんがネイティブ コード プロファイリングの素晴らしいサポートを持っており、カーネル スタックを見ることも問題なくできます。 JVM をサポートするためには、JIT コンパイルされたアドレスを関数名にマップする perf マップが必要です (補足すると、コンパイルされたフレームのみがサポートされます。インタープリター フレームは見えません)
そして、JIT スイッチ -XX:+PreserveFramePointer は perf が Java スタックを歩けるよう確実にするためのものです。 この種のアプローチを使用すると、インタプリタ・フレームを失ってしまいます。PreserveFramePointer フラグがない古い JVM をプロファイルすることはできません。JIT はコードを再コンパイルできるため、perfmap に古いエントリがある可能性があります。 HPROF は、JVM 内の CPU およびヒープ使用量をプロファイリングするために JDK に組み込まれているツールです。HPROF は実際には、JVM 起動時にコマンドライン・オプションを通じて動的にロードされ、JVM プロセスの一部となる JVM ネイティブ・エージェント・ライブラリです。 HPROFは、JVM起動時にコマンドラインオプションで動的にロードされ、JVMプロセスの一部になります。起動時にHPROFオプションを指定することで、ユーザーはHPROFにヒープやCPUのプロファイリング機能を要求できます。生成されるデータはテキスト形式またはバイナリ形式で、メモリ使用や効率の悪いコードに関するパフォーマンス問題の追跡や分離に使用することができます。 HPROF からのバイナリ形式のファイルは、ヒープに割り当てられたオブジェクトをブラウズするために HAT のようなツールで使用できます。
Conclusion
OpenJDK 内部 API コール AsyncGetCallTrace により、正直プロファイリングおよび非同期プロファイリングが「セーフポイントに苦しむ」という異常現象を克服したことが確認されました。しかし、JVMプロセスに固有なスレッドの詳細なプロファイリングを個別に提供することはできません。一方、Java Mission Control は、各プロセスに固有のスレッドを個別にプロファイルすることができ、その CPU 使用率でホットスレッドを監視することができます。
https://docs.oracle.com/javase/7/docs/technotes/tools/share/jps.html
JVMTI によるデバッグおよびプロファイリング エージェントの作成
http://www.oracle.com/technetwork/articles/java/jvmti-136367.html
The Pros and Cons of AsyncGetCallTrace Profilers
http://psy-lob-saw.blogspot.com/2016/06/the-pros-and-cons-of-agct.html
A sampling JVM profiler without the safepoint sample bias- (サンプリング JVM プロファイラーを使用したセーフポイント サンプルのバイアスなし)Honest Profiler
https://github.com/jvm-profiling-tools/honest-profiler
AsyncGetCallTrace + perf_events を特徴とする Java 用サンプリング CPU および HEAP プロファイラ
https://github.com/jvm-profiling-tools/async-profiler