 |
≫ |
|
|
 |
 |
| Java言語では、Javaオブジェクトに対するメモリ領域の割り当てや解放がJVMによって自動的に行われ、「ガベージ・コレクション」と呼ばれます。ガベージ・コレクションは、Javaプログラムのパフォーマンスに決定的な影響を与えるため、その振る舞いを把握することがチューニング作業においてきわめて重要となります。そこで今回は、Javaのガベージ・コレクションの役割を説明し、ログの記録方法などを解説します。 |
|
 |
 |
| 2004年4月 |
 |
|
 |
Javaプログラムの実行中には、Javaオブジェクトが生成されます。Javaオブジェクトは、Javaプログラムの起動時に生成される場合もあれば、実行中に必要に応じて生成されることもあります。いずれの場合も、JVM(Java仮想マシン)の内部で新しいJavaオブジェクトが作成されると、「ヒープ」と呼ばれるメモリ領域に、同オブジェクトを格納するための領域が割り当てられていきます。
このヒープのサイズは、JVMの起動時にオプションで指定することができます。例えば、以下のコマンドは、ヒープの最大値を240 MB に制限してJVM を起動する例です。
$ java -Xmx240m <クラス名>
この場合、もしJVM内部で大量のJavaオブジェクトが生成され、そのサイズが240MBを超えると、JVMは例外「OutOfMemoryException」を発してJavaプログラムの実行を停止します。
このように、全てのJavaオブジェクトは、JVMのヒープの内部に順次格納されていく仕組みです。 |
 |
Java言語では、ヒープ上のメモリ領域をJavaオブジェクトに割り当てたり、もしくは割り当て済みの領域を解放したりする処理を、プログラムコードに明示的に記述する必要がありません。これは、CやC++などの言語との大きな違いです。CやC++では、プログラムが使用するメモリ領域の割り当てや、使用済みの領域の解放を、プログラムコードから明示的に指示しなくてはなりません。
Java言語では、こうしたメモリ管理がJVMによって自動的に行われます。つまりJVMは、Javaプログラムのどこからも参照されなくなった不要なJavaオブジェクトを見つけ出し、そのメモリ領域を自動的に解放します。こうしたJavaオブジェクトの削除処理は「ガベージ・コレクション」と呼ばれます。JVM内部では、このガベージ・コレクションが独立したスレッドとして定期的に動作しています。ガベージ・コレクションが動作する頻度は、JVMのヒープ・サイズやヒープに対する需要、その他の様々な要因によって変化します。 |
 |
ガベージ・コレクションによるパフォーマンスへの影響
|
 |
 |
 |
 |
 |
| 図1:CPU負荷状態への影響 |
 |
 |
 |
| 図2:突発的なCPU負荷上昇のパターン |
 |
ここで注意すべき点は、JVMがガベージ・コレクションを実行している間、他の全てのスレッド(Javaプログラムを実行中のスレッドやJavaバイト・コードをコンパイル中のスレッドなど)の実行が停止してしまうことです。ガベージ・コレクションは、Javaプログラムのパフォーマンスに決定的な影響を与えるため、その振る舞いを把握することがきわめて重要となります。
図1は、8個のCPUを搭載したマシン上で1つのJVMを実行し、ガベージ・コレクションの動作によるCPU負荷状態への影響を示したものです。同図に示されるように、ガベージ・コレクションによって高負荷状態となるCPUは1個だけであり、他のCPUはほぼアイドル状態となっています。つまり、ガベージ・コレクションは、Javaプログラム全体をスローダウンさせる大きな要因となるわけです。
ガベージ・コレクションの挙動をコントロールするためには、JVM起動時のオプションを利用し、ヒープ・サイズ等を明示的に指定する必要があります。これについて詳しくは本連載で追って説明しますが、まずは最初の一歩として、JVM内部でどの程度の頻度でガベージ・コレクションが発生しているかを把握することから始めます。
HP-UXの場合、ガベージ・コレクションが頻繁に発生しているかどうかは、glanceやgpmを利用してその手がかりを得ることができます。例えば、gpmの画面上に図2のような突発的なCPU負荷上昇のパターンが見られる場合は、ガベージ・コレクションが必要以上に頻繁に発生している可能性が高いと言えます。また同図を詳しく見ると、ユーザー時間が断続的に大きく落ち込んでおり、ガベージ・コレクションによってCPUリソースが奪われていることが分かります。 |
| 本ページの内容は執筆時の情報に基づいており、異なる場合があります。 |
|