Javaパフォーマンス・チューニングのポイントにメソッド・コールの調査、メモリ・リークの発見があります。
メソッド・コールを調査することによって、実行時間やリソースの大半を消費しているメソッドを見つけ出し、その原因を特定し、パフォーマンス向上の糸口とすることができます。
その分析にはプロファイリング・ツールを用いるのが有効ですが、HPの「HPjmeter」(用語解説参照)も、こうした分析作業に最適な機能を備えています。
図1は、HPjmeterを利用し、Javaプログラム中のメソッドを呼び出し回数が多い順に一覧表示した画面です。この例では、「bel」メソッド(画面の最上行)の実行回数がほかのメソッドに比べて非常に多いことが示されています。
また、HPjmeterに備わるもう1つの計測項目である「Exclusive CPU Method Time(CPU占有時間)」を使用すれば、Javaプログラムの各メソッドの実行時間を知ることができます(図2)。
メソッドのコール回数はパフォーマンス低下の原因になりますが、メモリ・リークはもっと致命的なダメージをアプリケーションにもたらします。
用語解説
■HPjmeter
JVMのプロファイリング・ツール。メソッドのコール回数や経過時間、コールグラフのツリー表示、生成/残存オブジェクトなどをグラフィカルに表示する。アプリケーション解析に役立つ数多くの情報を提供する。詳細情報は、以下のページを参照。
http://www1.jpn.hp.com/products/software/development/java/tool/jmeter/index.html
メモリ・リークは、Javaプログラムの開発において最も注意すべきことの1つです。メモリ・リークによってJavaプログラムの実行中にJVMのヒープ・メモリが不足すると、OutOfMemoryエラーが発生し、プログラムの実行を継続できなくなったりJVMが異常終了したりします。
本連載の第2回「Javaのガベージ・コレクションを知る」で説明したとおり、Javaオブジェクトが必要とするメモリ領域は、JVMのヒープ・メモリから自動的に割り当てられます。また、不要になった(どこからも参照されなくなった)Javaオブジェクトはガベージ・コレクションによって収集され、そのメモリ領域は自動的に解放されます。よって、メモリ領域の確保や解放をプログラマが意識する必要がありません。そのため、Javaでは、CやC++のようなメモリ・リークが多発することはなくなりました。
例えばC++の場合、以下のようなコードによって、メモリ・リークが発生します。
ptr = new LargeObjectType(); //ptrを用いた処理 ptr = null;
ここでは、変数ptrにC++オブジェクトのポインタを割り当て、使用後にnullをセットしています。しかし、正しくは「delete ptr」と記述し、C++オブジェクトのメモリ領域を解放しなくてはなりません。こうしたdeleteし忘れが、C++におけるメモリ・リークの主な発生原因です。Javaでは、このdeleteに相当する作業をJVMのガベージ・コレクタが実行してくるため、こうしたタイプのメモリ・リークは起こらなくなりました。
しかし、Javaにおいても、メモリ・リークが完全になくなったわけではありません。例えば、JavaオブジェクトAのオブジェクト変数fooが、JavaオブジェクトBを参照しているケースを考えます。この場合、たとえBがプログラムの処理上は不要になったとしても、fooからBへの参照が存在する限り、Bはガベージ・コレクションの対象とはなりません。このように、プログラマが予想しないところでオブジェクトの参照が残ってしまうことを、「メモリ・リテンション」と呼びます。特に、コレクションや配列を参照元とするメモリ・リテンションが多発すると、解放されないJavaオブジェクトが継続的に増加し、メモリ・リーク状態に陥ります。
Copyright © ITmedia, Inc. All Rights Reserved.