ナビゲーションをスキップ

JRockit SDK ユーザーズ ガイド

  前 次 前/次ボタンと目次ボタンとの区切り線 目次  

BEA JRockit Memory Leak Detector の使い方

この製品は明示または黙示の保証あるいは BEA Systems, Inc によるサポートなしに「現状のまま」で提供されています。この製品は BEA Systems の公式なサポート対象製品になるかどうか定かではなく、エラーや誤りが含まれる可能性があります。 この製品の使用は BEA Systems からの承認なしにユーザの裁量にのみ任されます。 Memory Leak Detector の機能は将来の BEA JRockit のバージョンで利用できるかどうか定かではありません。 質問および問題はオンラインの BEA JRockit ニュースグループ (http://newsgroups.bea.com) を通じて報告できます。


 

BEA JRockit Memory Leak Detector は、BEA JRockit 上で実行される Java アプリケーション内のメモリ リークを検出するツールです。 メモリ リークとは、実際にはそのアプリケーションでこれ以上使用されないメモリをアプリケーション コードが保持し続けていることを表します。 BEA JRockit Memory Leak Detector は、割り当てられたオブジェクトの種類、回数、サイズ、およびオブジェクト相互の関連性に関する情報を提供するリアルタイムのプロファイリング ツールです。 他の同様のツールとは異なり、後で分析するためにヒープ全体のダンプを作成する必要はありません。 表示されるデータは実行中の JVM から直接取得され、JVM は比較的小さなオーバーヘッドで実行を続けることができます。 分析が行われるときはツールの接続を切断できるため、JVM は再び通常の速度で実行されます。 したがって、このツールはプロダクション環境での実行にも適しています。

このツールの目的は、メモリがリークしているオブジェクトのタイプを表示し、問題の原因を特定しやすくすることです。 もう一つの目的は、理解や知識を深めることにより、開発者が今後のプロジェクトで同様のプログラミング エラーを回避できるようにすることです。

注意 : BEA JRockit Memory Leak Detector の完全なバージョンを利用するには、JRockit JRockit 1.4.2_05 以降が必要です。

この節では、BEA JRockit Memory Leak Detector (以降は Memory Leak Detector という) の起動手順とメモリ リーク検出の手順について説明します。 内容は以下のとおりです。

 


Memory Leak Detector の起動

Memory Leak Detector を起動するには、BEA JRockit Management Console を起動する必要があります (BEA JRockit 1.4.2_05 以降)。

  1. BEA JRockit で Java アプリケーションを通常どおりに起動します。ただし、コマンドラインに -Xmanagement オプションを追加します。
  2. Management Console を起動し、前の手順で起動した BEA JRockit に接続します。 (詳しい手順については、「JRockit Management Console を起動する」を参照してください)。
  3. [MemLeak Detector] というタブをクリックします。
  4. 図 5-1 にこのタブの内容を示します。

    図 5-1 BEA JRockit Management Console 内の [MemLeak Detector] タブ

    BEA JRockit Management Console 内の [MemLeak Detector] タブ


     
  5. [Enable memleak system] をクリックします。 これで自動的に傾向分析が始まり、さまざまなオブジェクト タイプに関する情報が [Trend analysis] テーブルに表示されます。
  6. 各カラムが何を表すかについては、表 5-1 に詳しい説明があります。 メモリ リーク データの収集が始まると、「ManagementServer started trend analysis」というメッセージが JRockit から表示されます。

    表 5-1 カラムの説明

    カラムの見出し

    説明

    [Type]

    オブジェクトのタイプ。

    [Growth]

    このタイプのオブジェクトに割り当てられている 1 秒あたりのメモリ量 (バイト単位)。

    [% of heap]

    このタイプのオブジェクトが占めるヒープの割合。

    [Size]

    その割合に相当する KB 単位のサイズ。

    [#instances]

    現在参照されているこのタイプのオブジェクトの数。

 


Memory Leak Detector の使用

この節では、Memory Leak Detector の使い方について説明します。 内容は以下のとおりです。

メモリ リーク検出プロセスの概要

メモリ リーク検出プロセスには次の 3 つの段階があります。

  1. 傾向分析
  2. オブジェクト タイプの関係の調査
  3. インスタンスの調査

傾向分析では、絶えず更新されるオブジェクト タイプに関する情報を観察して、メモリが不審に増加しているオブジェクト タイプを見つけます。 このようなオブジェクト タイプは、メモリ リーク検出プロセスの次の段階で調査の対象となります。 傾向分析テーブルの情報は、ガベージ コレクションが実行されるたびに更新されます。

オブジェクト タイプの関係の調査では、オブジェクト タイプ (クラスなど) の間の参照パスを繰り返し追跡します。増加を続けるオブジェクト タイプの関係で注目すべきものを探し、その関係に関わるオブジェクト タイプを見つけることが目的です。 メモリが異常に増加しているオブジェクト タイプが見つかったら、メモリ リーク検出プロセスの 3 番目の段階に進みます。

インスタンスの調査では、異常なメモリ サイズのインスタンスや、異常な数の参照があるインスタンスを見つけて、そのインスタンスを調べます。 インスタンスを調べる際には、フィールド名、フィールドの型、フィールド値などの値が表示されます。 これらの値を利用して、アプリケーション コード内で正確なエラーの場所を探します。つまり、その特定のオブジェクト タイプの特定のインスタンスが割り当て、変更、または削除されている場所です (状況の示す内容によって異なります)。 不審なインスタンスに関わる部分にまで問題の場所を絞り込んでゆくと、メモリ リークを起こしている実際の問題をうまく見つけ出して、その問題を修正することができます。

開始

アプリケーションを分析するには、Memory Leak Detector を起動する必要があります (「Memory Leak Detector の起動」を参照)。

  1. [Enable memleak system] をクリックして、プロファイル データの連続的な更新を開始します。結果は図 5-2 のように表示されます。
  2. 図 5-2 メモリ リーク システムを有効にした場合

    メモリ リーク システムを有効にした場合


     

    赤でマークされた増加値は、100 バイト/秒を超える速度で増加しているオブジェクト タイプを示します。黄色でマークされた領域は、10 ~ 100 バイト/秒の速度で増加しているオブジェクト タイプを示します。これより低い速度で増加しているオブジェクト タイプは白です。

  3. [Freeze] をクリックして、データの連続的な更新を停止します。 停止すると、表示されたデータを分析することができます。
  4. 再びデータの収集を開始するには、[Continuous update] をクリックします。

    注意 : 連続的な更新を開始すると、傾向分析はゼロにリセットされます。つまり、[Continuous update] をクリックすると、表示されていたデータは失われます。

メモリ リークの検出

以下の節では、メモリ リーク検出プロセスに役立つように Memory Leak Detector を使用する方法について説明します。

  1. [Freeze] をクリックして、メモリ リーク データ収集の連続的な更新を停止します。
  2. JRockit プロセスから「ManagementServer stopped trend analysis」という通知が表示されます。

  3. 関心のあるオブジェクト タイプを選択します。 増加値の高い (赤や黄色でマークされた) オブジェクト タイプが該当するでしょう。
  4. 選択した項目を右クリックします。
  5. メニューが表示されます (図 5-3 を参照)。

    図 5-3 疑わしいオブジェクト タイプの選択

    疑わしいオブジェクト タイプの選択


     


     
  6. [Show types pointing to this type] を選択します。
  7. [Referring types] ウィンドウが表示されます。その特定のタイプのオブジェクトを指し示すオブジェクト タイプのリストが表示されています (図 5-4 を参照)。

    図 5-4 [Referring types] ウィンドウ : 疑わしいオブジェクト タイプの調査

    [Referring types] ウィンドウ : 疑わしいオブジェクト タイプの調査


     
  8. 調べたいオブジェクト タイプを選択して右クリックすると、さまざまな操作の選択肢が表示されます (図 5-5 を参照)。
  9. 図 5-5 操作の選択肢

    操作の選択肢


     
  10. 調べるオプションを選択します。
  11. インスタンスを選択して右クリックし、[Show instances pointing to this array] を選択して、図 5-6 の疑わしいインスタンスを追跡します。
  12. 表示された新しい [Referring instances] ウィンドウ (図 5-7 を参照) では、静的フィールドや、問題のインスタンスを参照しているスレッド ルート数を調べることができます。

    図 5-7 [Referring instances] ウィンドウ : 配列インスタンスを指し示すインスタンス

    [Referring instances] ウィンドウ : 配列インスタンスを指し示すインスタンス


     
  13. 参照しているインスタンスを選択して右クリックします。

  14.  
  15. [Inspect] をクリックします。 [Inspector] ウィンドウが表示されます (図 5-8 を参照)。
  16. インスタンスを調べる際には、アプリケーション コード内の特定のインスタンスを追跡するために必要なすべてのデータが得られます。 フィールド名、型、値などが表示されます。 これらの値とコードを照らし合わせることで、メモリ リークの原因を探すことができます。

    図 5-8 [Inspector] ウィンドウ : インスタンスの調査

    [Inspector] ウィンドウ : インスタンスの調査


     

場合によっては、リストが非常に長くなることがあります。その場合は、そのようなリストの表示結果について通知するメッセージが表示されます (図 5-9)。

図 5-9 非常に長いリストを表示しようとした場合

非常に長いリストを表示しようとした場合


 

実際のメモリ リークの見つけ方の例

この節では、検索領域を絞り込んでゆくことでメモリ リークを見つける方法を例を挙げて説明します。 検索領域を絞り込むと、問題の正確な場所をうまく見つけて、アプリケーションを変更することにより問題を解決することができます。

Memory Leak Detector を起動した後、アプリケーションの設計や目的を考えると増加しないはずなのに大きく増加しているオブジェクト タイプを調査の対象として選択します。 この例では、DemoObject オブジェクト タイプ (図 5-10) が該当します。 疑わしいオブジェクト タイプの行を選択して右クリックし、[Show types pointing to this type] メニュー オプションを選択します。

図 5-10 傾向分析から示されたオブジェクト タイプ DemoObject

傾向分析から示されたオブジェクト タイプ DemoObject


 

DemoObject を指し示す 1 つのオブジェクト タイプを示す [Referring types] ウィンドウ (図 5-4) が表示されます。 具体的には HashTable$Entry です。 この疑わしいメモリ リーク パスを追跡するには、該当する行を選択して右クリックし、[Show types pointing to this type] を再びクリックします。

表示された [Referring types] ウィンドウで、前述のオブジェクト タイプを指し示す 2 つのオブジェクト タイプに注目します。 1 つは HashTable$Entry[ ]、もう 1 つは HashTable$Entry です。 HashTable$Entry[ ] タイプからの参照の数が予想よりも大きいことに注目して、この配列型をさらに調べることにします。 この配列型の行を選択して右クリックし、[Show types pointing to this type] を選択します。 新しく表示された [Referring types] ウィンドウでは、オブジェクト タイプ HashTable がこの配列を指し示していることがわかります。

前のウィンドウに戻り、疑わしい配列型を再び選択します。 選択した項目を右クリックしたら、今度は [Show largest arrays of this type] を選択します。 [Largest Arrays] ウィンドウ (図 5-6) が表示されます。この配列のインスタンスが大きい順に 10 個まで表示されています。 この情報から、ある単一の配列インスタンスが大きなメモリ占有率の原因になっていることがわかります。

代わりに他のオプション [Show instances of this type pointing to <TYPE>] (この場合の TYPE は HashTable$Entry) を選択すると、参照の数が多いため JRockit プロセスへの接続が失われるおそれがあるという警告を示した、新しいウィンドウが表示されます。 つまり、HashTable$Entry[ ] は予想以上に多くのメモリを消費しており、HashTable$Entry への多数の参照を保持していることになります。

[Largest Arrays] ウィンドウに戻ります。 疑わしい項目 (メモリを最も多く占有しているインスタンス) を選択します。 [Show instances pointing to this array] を選択します。 [Referring instances] ウィンドウ (図 5-7) が表示されます。その配列を指し示すインスタンスのリストが表示されています。 HashTable インスタンス (図 5-11) です。

図 5-11 オブジェクト タイプの関係の調査結果

オブジェクト タイプの関係の調査結果


 

[Inspector] ウィンドウ (図 5-8) が表示されます。 このウィンドウでは、さまざまなフィールド名とその型および値を参照できます (図 5-12)。 これらのフィールドや値を、アプリケーション コードの特定の箇所に照らし合わせます。

図 5-12 インスタンスの調査は問題を当該コードに対応付けるのに役立つ

インスタンスの調査は問題を当該コードに対応付けるのに役立つ


 

この例からは、どこかで、HashTable によって保持されている HashTable$Entry[ ] に HashTable$Entry インスタンスを追加しているという結論を引き出すことができます。 また、アプリケーションでそのインスタンスを削除していないため、このタイプのオブジェクトが占有しているメモリが増え続けていると考えることができます。 この考えを確認するには、そのインスタンスのフィールド情報が示す場所で、コードを詳しく調べます。

メモリ リークの原因となっている場所をコードの中で確認したところ、HashTable 内で、HashTable$Entry オブジェクトが HashTable$Entry[ ] に追加された後であることがわかりました。 アプリケーションは HashTabe$Entry オブジェクトを 1 つだけ残して全部削除しており、1 つ違い (off-by-one) エラーが原因で最後のインスタンスを見逃していました。このエラーはこの種のメモリ リークの原因としてよく見られるエラーです。

 


BEA JRockit の改良に関するご協力のお願い

Memory Leak Detector を使用すると、オブジェクト タイプの割り当てに関する統計情報を簡単に入手することができます。 このツールは、開発者がメモリ リークを簡単に見つけ出したり、プログラム エンジニアリングの重要なポイントを理解するのに役立つように設計されています。

このツールの改良方法や開発環境における一般的な使われ方など、上記の目的に沿った提案があればぜひお寄せください。 弊社では、こうした情報をもとに、このツールを今後どのように改良すればよいかを判断することができます。

フィードバックや使い方に関するアイデアは、電子メールで下記の宛先までお送りください。

jrockit-improve@bea.com

BEA Systems によるフィードバックの利用について

フィードバックは Memory Leak Detector の設計を担当する開発チームによって検討されます。 集まったアイデアを参考に、BEA JRockit のツールをより使いやすくなるように改良します。 このツールを開発する目的は、メモリ リークを見つけるという難しい作業を簡単にして、開発者が効率的に作業できるようにすることです。

BEA JRockit には扱いやすく好評なツールが既にいくつもありますが、Java Runtime Environment を使用する開発者との緊密な対話を維持できるように、BEA Systems では BEA JRockit の改良方法を絶えず探り続けています。 Memory Leak Detector はその方法の 1 つです。

 


Memory Leak Detector に対する BEA JRockit のサポート

Memory Leak Detector を完全にサポートしているのは、BEA JRockit の最近のバージョン (BEA JRockit 1.4.2_05) だけです。

 


よくある質問

Memory Leak Detector に関するよく寄せられる質問は以下のとおりです。

BEA Systems はこのツールの出力の精度を保証していますか

このツールはサポート対象の製品ではないため、提供されるデータの正確性や Memory Leak Detector を使用しているときの製品の安定性に関する保証はありません。

Memory Leak Detector はオーバーヘッドを引き起こしますか

メモリ リーク検出プロセスの最初の段階では、表示データが絶えず更新されますが、この段階でのオーバーヘッドは非常に小さいものです。 2 番目と 3 番目の段階で発生するオーバーヘッドのみがガベージ コレクションに加わりますが、ほとんどの場合は無視してかまいません。 全体として特にオーバーヘッドはなく、アプリケーションの速度や結果には影響を与えません。

Memory Leak Detector についてはどのようなサポートがありますか

Memory Leak Detector は現在、メモリ リークの検出に役立つように参考として現状のままで提供されており、BEA Support によるサポートはありません。

Memory Leak Detector について話し合えるフォーラムはありますか

質問がある場合は、BEA JRockit の一般的な問題に関するニュースグループで共有できます。このニュースグループはエンジニアリング チームによってモニタされています。 ニュースグループにアクセスするには、以下に移動してください。

http://newsgroups.bea.com

 


確認済みの問題

他のインスタンスを参照しているインスタンスを表示するウィンドウに、静的フィールドやスレッド ルート数が正しく表示されない場合があります。 その場合はメモリ リーク検出プロセスを再び開始してください (メモリ リーク システムの連続的な更新を開始してから停止します)。 正しいデータが表示されるようになります。

 

ナビゲーション バーのスキップ  ページの先頭 前 次