Jump to content 日本-日本語

製品  >  ソフトウェア  >  HP-UX   >  Knowledge-on-Demand  >  Javaパフォーマンス・チューニング

Javaパフォーマンス・チューニング

第6回:メモリ・リーク解析とHotSpot JVM

HP-UX/Integrityサーバー お問い合せ
コンテンツに進む
メモリ・リーク解析とHotSpot JVM
今回は、HPjmeterに備わるCompare機能を活用し、一定時間が経過したあとの残存オブジェクトを洗い出し、メモリ・リークの原因を探る方法を説明します。また後半では、HotSpot JVMではパフォーマンスを改善できないケースを明らかにし、その対処方法を学びます。
Javaパフォーマンス・チューニング 第6回
HPjmeterによるメモリ・リーク解析
HotSpot JVMの特性を知る
2004年8月
ページ: 1   2   |   次へ 

HPjmeterによるメモリ・リーク解析


まず前半では、HPが提供するプロファイリング・ツールHPjmeterを利用したメモリ・リーク解析の方法を解説します。

前回説明したとおり、Javaオブジェクトが必要とするメモリ領域は、JVMのヒープ・メモリから自動的に割り当てられます。また、不要になった(どこからも参照されなくなった)Javaオブジェクトはガベージ・コレクションによって収集され、そのメモリ領域は自動的に解放されます。よって、メモリ領域の確保や解放をプログラマが意識する必要がありません。そのため、Javaでは、CやC++のようなにメモリ・リークが多発することはなくなりました。

しかし、Javaにおいても、メモリ・リークが完全になくなったわけではありません。たとえば、JavaオブジェクトAのオブジェクト変数fooが、JavaオブジェクトBを参照しているケースを考えます。この場合、たとえBがプログラムの処理上は不要になったとしても、fooからBへの参照が存在するかぎり、Bはガベージ・コレクションの対象とはなりません。このように、プログラマが予想しないところでオブジェクトの参照が残ってしまうことを、「メモリ・リテンション」と呼びます。とくに、コレクションや配列を参照元とするメモリ・リテンションが多発すると、解放されないJavaオブジェクトが継続的に増加し、メモリ・リーク状態に陥ります。

メモリ・リーク解析の1つの方法として、ガベージ・コレクションを強制実行したあとにプログラムを終了させる方法があります。これを実施するには、プログラムを終了させる部分で以下のように記述します。

System.gc()
System.runFinalization()
System.gc()
System.exit()

このとき、HP-JVMの起動のオプションには「-Xrunhprof:heap=all,cutoff=0」を追加しておきます。これにより出力されるプロファイル・データをHPjmeterで解析すれば、プログラムが終了した時点で残存するオブジェクトの状態を観察できます。

また、この方法を使えば、一定期間中の残存オブジェクトの増減を知ることも可能です。たとえば、プログラムが1時間動作する際に残存するオブジェクトを観察したいとします。そのためには、プログラムを2回実行し、2回目は1回目より1時間長く動作させます。そして、HPjmeterのCompare機能を利用して、得られた2つのプロファイル・データを比較します。

ここでは、プログラムを1時間実行したときと、2時間実行したときの、それぞれのプロファイル・データをHPjmeterでオープンします。具体的には、以下のメニュー操作を実施します。

  1. [File]→[Open]を選択し、2つのファイルを続けて開きます
  2. [File]→[Compare]を選択すると、2つのデータの概要が表示されます
  3. [Metric]→[Residual Objects(Count)]を選択します

以上の操作を行うと、以下の画面が表示されます。

図1:HPjmeterのCompare機能による比較
図1:HPjmeterのCompare機能による比較

図1の比較結果を見ると、1時間目から2時間目の間に、Authorizeオブジェクトが8017個も増加していることがわかり、メモリ・リークの発生が疑われます。そこで、このAuthorizeオブジェクトをさらに詳しく解析してみます。まずは、あとで検索しやすくするため、同オブジェクトの行をマークしておきます。

  1. Authorizeオブジェクトの行をクリックし、[Edit]→[Mark to Find]を選択してマークします

参照グラフツリーの解析


続いて、以下の操作を行い、2時間実行したプロファイル・データをもとにしてAuthorizeオブジェクトの解析を行います。

  1. [File]→<プロファイル・データのファイル名>を選択します
  2. [Metric]→[Reference Graph Tree]を選択します

これにより、2時間実行した時点で、JVM内の全オブジェクトが互いにどのように参照し合っているのかを示すグラフツリーが表示されます。この参照グラフツリーの中から、Authorizeオブジェクトのツリーを検索します。

  1. [Edit]→[File]を選択します

このとき、検索結果を一度にすべて表示するか、いずれか1つを表示するかを選択するダイアログが現れます。Authorizeオブジェクトの数が多いので、ここでは[Find Any]を選択します。これにより表示されるツリーを確認すれば、多数のAuthorizeオブジェクトの参照元となっているオブジェクトがどれかを知ることができます。

図2:Authorizeオブジェクトの参照グラフツリーの表示
図2:Authorizeオブジェクトの参照グラフツリーの表示

また、HPjmeter 1.2.1以降では、メモリ・リークの疑いのあるオブジェクトを検出する機能が追加されました。ただし同機能は、「参照が1つしかないオブジェクトはメモリ・リークが疑われる」という簡単な経験則に基づいています。そのため、必ずしもそれがメモリ・リークを見つけられるとは限りませんが、着目すべき部分を知る手段としては有効です。この機能を利用するには、以下の操作を行います。

  1. [Guess]→[Memory Leaks]を選択します

これにより、メモリ・リークの疑いのあるオブジェクトのIDとサイズ(バイト数)が表示されます。これを先ほどの参照グラフツリーと比較すれば、同じオブジェクトであることがわかります。

図3:メモリ・リークの疑いのあるオブジェクトと比較
図3:メモリ・リークの疑いのあるオブジェクトと比較

こうした一連の操作によって、メモリ・リークの可能性の高いオブジェクトが洗い出されたので、このあとは同オブジェクトに対象を絞ってさらなる解析を進めることとなります。このように、HPjmeterを利用することで、メモリ・リーク解析を効率的に実施することができます。

連載記事一覧 ページ: 1   2   |   次へ  次のページへ

本ページの内容は執筆時の情報に基づいており、異なる場合があります。

お問い合わせ

ご購入前のお問い合わせ


ご購入後のお問い合わせ

HPEサポートセンター
製品の標準保証でご利用いただける無償のサービスです。

ショールーム

ショールーム 導入をご検討のお客様へ
業務アプリケーションの継続・標準化・開発性とシステム担当者様、システム開発者様が抱える悩み・疑問に対する解決策実体験して頂けます。
印刷用画面へ
プライバシー ご利用条件・免責事項