Oracle® Solaris Studio 12.4: パフォーマンスアナライザチュートリアル

印刷ビューの終了

更新: 2014 年 12 月
 
 

Java ガベージコレクタの動作の理解

この手順では、Java ガベージコレクションを呼び出すアクティビティーを調べて、「タイムライン」ビューの使用方法と「タイムライン」でのビューモード設定の影響を示します。

  1. ビューモードを「ユーザーモード」に設定して、ナビゲーションパネルで「タイムライン」を選択し、このハイブリッド Java/ネイティブアプリケーション jsynprog の実行の詳細を表示します。

    image:ユーザーモードの「タイムライン」ビュー

    上部に「CPU 使用率標本」バーと、3 つのスレッドのプロファイルデータが表示されるはずです。スクリーンショットでは、プロセス 1、スレッド 2、14、15 のデータを参照できます。表示されるスレッドの番号付けと数は、OS、システム、および使用している Java のバージョンによって異なる可能性があります。

    この例では、最初のスレッドである T:2 というラベルが付いたスレッド 2 のみで、「ユーザー CPU」としてマイクロステートが表示されます。ほかの 2 つのスレッドはそのすべての時間を JVM 同期の一部である「ユーザーロック」の待機に使用します。

  2. ビューモードを「エキスパートモード」に設定します。

    ユーザースレッド T:2 はほとんど変更されていないように見えますが、「タイムライン」ビューにはより多くのスレッドが表示されるようになったはずです。

  3. タイムラインの上部にある縦方向ズームコントロールを使用して、すべてのスレッドを表示できるようにズームを調整します。

    次のスクリーンショットでは、縦方向ズームコントロールは赤色で強調表示されています。マイナスボタンをクリックして、20 個のスレッドすべてが表示されるまでスレッド行の高さを縮小します。

    image:「タイムライン」ビューの縦方向ズームコントロール
  4. 「タイムライン」ツールバーの「呼び出しスタック関数の色」ボタンをクリックして、関数 Routine.memalloc() の色を赤色に設定します。

    「関数の色」ダイアログの「凡例」で Routine.memalloc() 関数を選択して、「スイッチ」内の赤色のボックスをクリックして「選択した関数の設定」をクリックします。

    image:「タイムライン」ビューで色を変更するための「関数の色」ダイアログ

    スレッド 2 のスタックの上部に赤色のバーが表示されるようになりました。その領域は、Routine.memalloc() ルーチンが実行されていた時間の一部を表しています。

    縦方向にズームアウトして呼び出しスタックのフレームをさらに表示して、対象の時間の領域に横方向にズームインする必要がある場合があります。

  5. 「タイムライン」ツールバーの横方向スライダを使用して、スレッド T:2 内の個々のイベントが表示されるほど近くまでズームインします。

    キーボードの + キーをダブルクリックするか押すことでズームすることもできます。

    image:1 行に 3 つのデータバーを表示するためにズームインされた「タイムライン」ビュー

    タイムラインの各行には、実際には 3 つのデータバーが含まれています。上部のバーは、そのイベントの呼び出しスタックの表現です。中央のバーには、すべてのイベントを表示するために、イベントが近すぎる間隔で一緒に発生した場合は常に黒色のティックマークが表示されます。つまり、ティックマークが表示された場合、そのスペースに複数のイベントがあることがわかります。

    下部のバーはイベント状態のインジケータです。T:2 の場合、下部のバーは緑で、「ユーザー CPU 時間」が使用されていたことを示しています。スレッド 3 - 12 の場合、下部のバーは灰色で、「ユーザーロック時間」を示しています。

    ただし、ユーザースレッド T:2 は赤色で示されているルーチン Routine.memalloc 内にあるため、これらのスレッド 3 - 12 すべてに、同時に到着するクラスタ化されたイベントが多数あります。

  6. Routine.memalloc 領域までズームインして、次を行なってその領域のみを含めるためにフィルタします。

    • 上部に赤色の関数呼び出しがある Routine.memalloc 領域の先頭近くにある T:2 バーをクリックします。

    • クリックして、呼び出しスタックの先頭にある赤色が終わるその領域の終わりの近くまでマウスをドラッグします。

    • 右クリックして、「ズーム」>「選択した時間範囲まで」を選択します。

    • まだ範囲を選択した状態で、右クリックして「フィルタの追加: 選択した時間範囲のイベントのみを含める」を選択します。

    ズーム後に、スレッド 3 - 12 には、「ユーザー CPU 時間」を示すために緑になっているいくつかのイベント状態と、「CPU 待ち時間」を示すために赤色になっている少数のイベント状態があることがわかります。

  7. スレッド 3 - 12 でいずれかのイベントをクリックすると、それぞれのスレッドのイベントにスタックの GCTaskThread::run() が含まれていることが「呼び出しスタック」パネルでわかります。

    これらのスレッドは、JVM がガベージコレクションを実行するために使用するスレッドを表します。「ユーザー CPU 時間」を多く使用しないため、ユーザースレッドが Routine.memalloc 内にあるときに GC スレッドが実行され、それ以外の場合は実行されません。

    image:タイムライン領域へのズームイン
  8. 「関数」ビューに戻って、「包括的 CPU 合計」列ヘッダーをクリックして、包括的 CPU 時間合計でソートします。

    最上位の関数の 1 つが GCTaskThread::run() 関数であることがわかるはずです。これによって、ユーザータスク Routine.memalloc が何らかの方法でガベージコレクションを呼び出しているこという結論に達します。

  9. Routine.memalloc 関数を選択して、「ソース」ビューに切り替えます。

    image:Routine.memalloc 関数の「ソース」ビュー

    ソースコードのこのフラグメントから、ガベージコレクションが呼び出されている理由が簡単にわかります。このコードは、100 万個のオブジェクトの配列を割り当てて、同じ場所にありそれぞれがループを通過するこれらのオブジェクトへのポインタを格納します。これによって古いオブジェクトは使用されなくなるため、不要になります。

次のセクションに進みます。