Java Platform, Standard Editionトラブルシューティング・ガイド
目次      

2.8 HPROF

HPROFは、すべてのJDKリリースに付属しているヒープおよびCPUプロファイリング用のツールです。これは、Java Virtual Machine Tool Interface (JVM TI)を使用してJava仮想マシン(JVM)とインタフェースを取る、動的リンク・ライブラリ(DLL)です。このツールは、プロファイル情報をファイルまたはソケットにASCII形式またはバイナリ形式で書き込みます。この情報はさらに、プロファイラ・フロント・エンド・ツールを使用して処理できます。

HPROFツールでは、CPU使用率、ヒープ割当ての統計、およびモニター競合プロファイルを表示できます。さらに、完全なヒープ・ダンプや、JVM内のすべてのモニターとスレッドの状態を報告できます。問題の診断に関して、HPROFはパフォーマンス、ロック競合、メモリー・リークなどの問題を分析する際に役立ちます。

JDKにはHPROFライブラリだけでなく、HPROFのソースもJVM TIのデモ・コードとして含まれています。このコードは$JAVA_HOME/demo/jvmti/hprofディレクトリにあります。

次の項では、HPROFツールによるトラブルシューティング手法について説明します。

2.8.1 HPROFツールによるトラブルシューティング

例2-6に示すように、HPROFツールを起動します。

HPROFは要求されたプロファイルの種類に応じて、関連するイベントを送信するようにJVMに指示します。その後、ツールはイベント・データをプロファイル情報に処理します。たとえば、次のコマンドはヒープ割当てプロファイルを取得します。

例2-7に示すように、HPROFエージェントにhelpオプションを指定すると、オプションの完全な一覧が出力されます。

例2-7 HPROFエージェントのヘルプ

$ java -agentlib:hprof=help
     HPROF: Heap and CPU Profiling Agent (JVMTI Demonstration Code)
hprof usage: java -agentlib:hprof=[help]|[<option>=<value>, ...]
Option Name and Value  Description                    Default
---------------------  -----------                    -------
heap=dump|sites|all    heap profiling                 all
cpu=samples|times|old  CPU usage                      off
monitor=y|n            monitor contention             n
format=a|b             text(txt) or binary output     a
file=<file>            write data to file             java.hprof[{.txt}]
net=<host>:<port>      send data over a socket        off
depth=<size>           stack trace depth              4
interval=<ms>          sample interval in ms          10
cutoff=<value>         output cutoff point            0.0001
lineno=y|n             line number in traces?         y
thread=y|n             thread in traces?              n
doe=y|n                dump on exit?                  y
msa=y|n                Oracle Solaris micro state accounting n
force=y|n              force output to <file>         y
verbose=y|n            print messages about dumps     y
Obsolete Options
----------------
gc_okay=y|n
<>
Examples
--------
  - Get sample cpu information every 20 millisec, with a stack depth of 3:
      java -agentlib:hprof=cpu=samples,interval=20,depth=3 classname
  - Get heap usage information based on the allocation sites:
      java -agentlib:hprof=heap=sites classname
Notes
-----
  - The option format=b cannot be used with monitor=y.
  - The option format=b cannot be used with cpu=old|times.
  - Use of the -Xrunhprof interface can still be used, e.g.
       java -Xrunhprof:[help]|[<option>=<value>, ...]
    will behave exactly the same as:
       java -agentlib:hprof=[help]|[<option>=<value>, ...]
Warnings
--------
  - This is demonstration code for the JVMTI interface and use of BCI,
    it is not an official product or formal part of the JDK.
  - The -Xrunhprof interface will be removed in a future release.
  - The option format=b is considered experimental, this format may change
    in a future release.

ヒープ・プロファイル情報(サイトとダンプ)はデフォルトで、現在の作業ディレクトリ内のjava.hprof.txtに(ASCIIで)書き出されます。

出力は通常、JVM終了時に生成されますが、それを無効にするには、doe (終了時にダンプ)オプションをnに設定します(doe=n)。さらに、[Ctrl]+[\] (OracleおよびLinuxオペレーティング・システムの場合)または[Ctrl]+[Break] (Windowsの場合)を押すと、プロファイルが生成されます。Oracle SolarisおよびLinuxオペレーティング・システムでは、プロセスがQUITシグナルを受信したとき(kill -QUIT pid)にもプロファイルが生成されます。[Ctrl]+[\]または[Ctrl]+[Break]を複数回押すと、1つのファイルに複数のプロファイルが生成されます。

ほとんどの場合、出力にはトレース、スレッド、およびオブジェクトのIDが含まれています。それぞれのタイプのIDは通常、ほかのIDとは異なる番号から始まります。たとえば、トレースは300000から始まることがあります。

2.8.2 ヒープ割当てプロファイルheap=sites

例2-8は、一連の入力ファイルでのJavaコンパイラ(javac)の実行により生成されたヒープ割当てプロファイルです。ここでは、プロファイラ出力の一部のみを示します。

ヒープ・プロファイル内の重要な情報は、プログラムのさまざまな部分で行われる割当ての量です。前述のSITESレコードは、合計領域の44.13%がjava.util.zip.ZipEntryオブジェクトに割り当てられたことを示しています。

割当てサイトをソース・コードに関連付けるには、ヒープ割当ての原因となった動的スタック・トレースを記録するのが早道です。例2-9は、プロファイラ出力の別の部分を示しています。前述の出力では4つの割当てサイトによって参照されていたスタック・トレースを示しています。

スタック・トレースの各フレームには、クラス名、メソッド名、ソース・ファイル名、および行番号が含まれています。ユーザーは、HPROFエージェントによって収集されるフレームの最大数を設定できます。デフォルトの上限は4です。スタック・トレースには、ヒープ割り当てを行なったメソッドだけでなく、最終的にメモリー割当てが発生する呼出しを行なったメソッドも表示されます。

2.8.3 ヒープ・ダンプ・プロファイルheap=dump

ヒープ・ダンプはheap=dumpオプションを使用して取得できます。ヒープ・ダンプの形式は、formatオプションの設定に応じてASCII、バイナリのいずれかです。jhatなどのツールではバイナリ形式を使用するので、format=bオプションが必要です。詳細は、「jhatユーティリティ」を参照してください。バイナリ形式が指定された場合、プリミティブ型のインスタンス・フィールドとプリミティブ配列の内容がダンプに含まれます。

例2-10は、javacコンパイラの実行から、ヒープ内の現在のライブ・オブジェクトの完全なダンプをASCIIテキスト形式で生成するコマンドを示しています。

出力は大きなファイルになります。これは、ガベージ・コレクタによって決定されたルート・セットと、そのルート・セットから到達可能なヒープ内の各Javaオブジェクトごとのエントリから構成されます。次は、サンプル・ヒープ・ダンプから選択されたいくつかのレコードです。

各レコードは、ルート、オブジェクト・インスタンス、クラス、または配列を表すROOTOBJCLS、またはARRです。16進数は、HPROFによって割り当てられた識別子です。これらの数値は、あるオブジェクトから別のオブジェクトへの参照を示すために使用されます。前述の例で、java.lang.Threadのインスタンス50000114には、そのスレッド・グループ(50008c6c)と他のオブジェクトへの参照があります。

一般に出力のサイズは非常に大きいので、ツールを使ってヒープ・ダンプの出力を視覚化または処理する必要があります。そのようなツールの1つがjhatです。「jhatユーティリティ」を参照してください。

2.8.4 CPU使用率サンプリング・プロファイルcpu=samples

HPROFツールは、スレッドのサンプリングによってCPU使用率の情報を収集できます。例2-11は、javacコンパイラの実行によりCPU使用率サンプリング・プロファイルを生成する方法を示しています。

HPROFエージェントは、実行中のすべてのスレッドのスタックを定期的にサンプリングし、もっとも頻繁にアクティブになるスタック・トレースを記録します。上のcountフィールドは、特定のスタック・トレースがアクティブであることが見つかった回数を示しています。これらのスタック・トレースは、アプリケーション内のCPU使用率のホット・スポットに相当します。

2.8.5 CPU使用時間プロファイルcpu=times

HPROFツールは、CPU使用率の情報を収集するために、あらゆるメソッドの入口と出口にコードを挿入し、それによって正確なメソッド呼出し回数と各メソッド内で費やされた時間を追跡します。このプロセスではバイトコード・インデックス(BCI)が使用されるため、実行速度はcpu=samplesオプションよりもかなり低下します。例2-12は、javacコンパイラの実行から収集されたCPU使用時間プロファイル出力の一部を示しています。

この出力で、countはこのメソッドに入った本当の回数を表し、パーセンテージはこのメソッドで費やされたスレッドCPU時間の尺度を表します。

目次      

Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.