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

JRockit SDK ユーザーズ ガイド

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

BEA JRockit メモリ管理システムの使い方

メモリ管理は効果的な「ガベージ コレクション」に依存しています。ガベージ コレクションとは、ヒープから不要になったオブジェクトを消去して、その領域を新しいオブジェクトのために解放するプロセスです。メモリ管理を効率的に行うと、効率的な処理が実現されます。BEA JRockit の統合ガベージ コレクタでは、メモリ スループット、またはコレクションに起因する休止時間のどちらか 1 つの優先順位に基づいて機能する動的なガベージ コレクタを選択できます。統合ガベージ コレクタは、実行中に、あらかじめ定義されたヒューリスティックに基づいて、使用するコレクション アルゴリズムを決定し、個々のケースの状況に応じてそのアルゴリズムを変更するという点で「動的」です。このガベージ コレクタを実行するための実際のアルゴリズムを指定する必要はありません。

場合によっては、動的なガベージ コレクションが、メモリを解放する最も効率的な方法にならないこともあります。そのような場合に備えて、BEA JRockit には「静的な」コレクタも数多く用意されています。静的なコレクタを使用するには、起動時に実際のコレクタを指定します (-Xgc:<collectorName>)。または、起動時に選択した JVM モードによって決定されるデフォルトのコレクタを使用します。

この節では、これらのガベージ コレクション方式の使い方について説明します。内容は以下のとおりです。

 


マークアンドスイープ コレクション モデル

統合ガベージ コレクタは、世代別としてもシングルスペースとしても (つまり、「ナーサリ」の有無にかかわらず) 動作する「マークアンドスイープ」コレクタです (後述の「世代別」を参照)。どちらのマークアンドスイープ オプションでも、コンカレント アルゴリズムまたはパラレル アルゴリズムを実装できます。ガベージ コレクションのオプションとアルゴリズムの詳細については、「ガベージ コレクタの組み合わせ」を参照してください。

マークアンドスイープ コレクタは 3 つのパスから成るモデルで、参照されていないすべてのオブジェクトを解放します。次の手順のように動作します。

  1. 最初のパスでは、システム内で、マーク ビットがセットされているすべてのオブジェクトをクリアします。マーク ビットは、ブロックにガベージが含まれている場合にそのブロックが使用中かどうかを識別するものです。
  2. 2 番目のパス (「マーク」フェーズ) では、プログラムのアクセス可能なルートから始めて (通常は、グローバル、スタック、レジスタの順に) すべてのポインタをトラバース (探索) し、トラバースした各オブジェクトをマークします。
  3. 3 番目のパス (「スイープ」フェーズ) では、ヒープを直線的に再走査して、マークされていないすべてのオブジェクトを削除します。

 


ガベージ コレクタの組み合わせ

統合ガベージ コレクタは、以下の 2 つのガベージ コレクタ オプションと、

以下の 2 つのガベージ コレクション アルゴリズムのさまざまな組み合わせ (または「ステート」) で構成されます。

世代別

世代別ガベージ コレクションでは、ヒープは古い世代と若い世代 (「ナーサリ」とも呼ばれる) の 2 つのセクションに分かれています。オブジェクトがナーサリに割り当てられて、ナーサリが一杯になると、JVM は処理を停止して (つまり、すべてのスレッドを停止して)、生存しているオブジェクトを若い世代から古い世代に移動します。同時に、古いコレクタ スレッドが背後で動作しており、古い世代でオブジェクトを生存中としてマークし、不要になったオブジェクトは削除して、JVM に空いた領域を返します。

シングルスペース

ガベージ コレクションのシングルスペース オプションの場合、すべてのオブジェクトは、経過時間に関係なく、ヒープ上の 1 つの領域内で生存期間を過ごします。つまり、シングルスペース ガベージ コレクタにはナーサリはありません。

コンカレント

コンカレント ガベージ コレクション アルゴリズムでは、他のすべての処理と「コンカレント」(同時) に、マークとスイープを行います。つまり、Java スレッドを停止しないでガベージ コレクションを完了します。

パラレル

パラレル ガベージ コレクション アルゴリズムでは、ヒープが一杯になったときに Java スレッドを停止し、すべての CPU を使用して、ヒープ全体のマークとスイープを完了します。パラレル コレクタはコンカレント コレクタよりも休止時間が長くなりますが、スループットを最大にします。このようにパフォーマンスが最大になるため、アプリケーションで長い休止時間を許容できる場合は、シングル CPU マシン上でもパラレル ガベージ コレクタをお勧めします。

 


動的なガベージ コレクタの実行

統合ガベージ コレクタは、マークアンドスイープ モデルの中で、前述のオプションとアルゴリズムを組み合わせてコレクションを実行します。コレクタは、使用するヒューリスティックに応じて、コンカレントまたはパラレルのマーク フェーズと、コンカレントまたはパラレルのスイープ フェーズにおいて、世代別 コレクタまたはシングルスペース コレクタを採用します。

動的な (「最適化」) ガベージ コレクタの主な利点は、要件に最も適したコレクタを実行するために、ユーザ側では、コレクション中の最適なメモリ スループットと最小の休止時間のどちらの方がアプリケーションにとって効果的なのかを決定するだけでよい点です。自分のアプリケーションの動作を理解しているだけでよく、ガベージ コレクション アルゴリズムやさまざまな組み合わせについて理解する必要はありません。

注意 : -Xgcprio は BEA JRockit 1.4.2_08 以前のリリースではサポートされていません。このオプションがサポートされているのは 1.4.2_10 以降のリリースのみです。

統合ガベージ コレクタを起動するには、-Xgcprio コマンドライン オプションに throughput パラメータまたは pausetime パラメータを指定します。どちらを指定するかは、使用する優先順位によって異なります。

-Xgcprio:<throughput|pausetime>

表 3-1 では、動的なガベージ コレクタを起動する際の優先順位と、その優先順位の選択に使用するパラメータを示します。

表 3-1 -Xgcprio オプションの優先順位

優先順位

説明

パラメータ

メモリ スループット

通常、メモリ スループットはガベージ コレクションにとって最も重要な優先順位であり、ほとんどの場合はこちらを選択します。メモリ スループットは、あるオブジェクトが参照されなくなった時点から、返還を要求されて空きメモリとして返される時点までの時間を評価するものです。メモリ スループットが高くなるほど、2 つのイベントの間の時間は短くなります。また、メモリ スループットが高くなるほど、必要なヒープは小さくなります。

throughput

休止時間

休止時間とは、ガベージ コレクタがガベージ コレクション中にすべての Java スレッドを休止する時間の長さです。休止時間が長くなるほど、システムの応答が遅くなります。アプリケーション実行中の最長休止時間と平均休止時間は、JVM のチューニングに非常に役立つ値です。一般に、システムが長い休止時間に影響を受けやすい場合は、優先順位として休止時間を選択します。

pausetime

優先順位を選択して JVM を起動すると、動的なガベージ コレクタは優先順位に基づいてパフォーマンスを最適化するガベージ コレクション ステートを選択します。-Xgcprio:throughput を指定すると、スループットが最適化されるモードが選択され、-Xgcprio:pausetime を指定すると、休止時間が可能な限り短くなるモードが選択されます。

 


静的なガベージ コレクション方式の使用

状況によっては、動的なガベージ コレクタを使用しない方がよい場合もあります。そのような場合は、デフォルトで起動される静的なコレクタを使用するか、BEA JRockit の以前のバージョンに用意されていた下位互換性のあるガベージ コレクタの 1 つを使用することができます。-Xgcprio を指定して起動する動的なガベージ コレクタとは違って、静的なコレクタでは、最初に選択されたガベージ コレクション アルゴリズムを変更できません。アルゴリズムの変更によるパフォーマンスの最適化は行われません。

この節の内容は以下のとおりです。

下位互換性のあるガベージ コレクタの使用

BEA JRockit SDK の以前のバージョンに用意されていた 3 種類のガベージ コレクタは、このバージョンでも使用できます。場合によっては、これらのコレクタのパフォーマンスの方が、統合ガベージ コレクタまたは -server フラグまたは -client フラグを設定したデフォルトのコレクタよりニーズに適していることがあります。また、JRockit の以前のバージョン用に記述したスクリプトがあり、その中でこれらのコレクタを実装している場合、そのスクリプトは一切修正することなく引き続き使用できます。ただし、スクリプトで世代別コピー ガベージ コレクタを使用している場合は除きます (このガベージ コレクタは使用できなくなりました)。当然ですが、スクリプトを変更して統合ガベージ コレクタを実装することはできます。

使用できるガベージ コレクタ (と起動するコマンド) は次のとおりです。

長所と短所

表 3-2 に、各ガベージ コレクタの長所と短所を示します。

表 3-2 ガベージ コレクタの長所と短所

ガベージ コレクタ

長所

短所

シングルスペース コンカレント

  • 実質的にすべての休止をなくす。

  • ギガバイトサイズのヒープを扱うことができる。

  • -client オプションを指定して実行する場合のデフォルト ガベージ コレクタ。

  • 休止をなくすためにメモリを引き換えにする。

  • 通常の Java スレッドで、このコレクタが収集できるよりも多くのガベージが作成される場合は、コレクタがそのサイクルを完了するまで Java スレッドが待機する間に休止が発生する。

  • コレクション中にプログラムがメモリ不足になる場合は効果的でない。

世代別コンカレント

  • 実質的にすべての休止をなくす。

  • シングルスペース コンカレント ガベージ コレクタよりもメモリ スループットが高くなる。

  • 古い領域は同じ速度で一杯にならないため、コレクション中に割り当て可能なメモリが不足するリスクが減る。

  • 休止をなくすためにメモリを引き換えにする。

  • 通常の Java スレッドで、このコレクタが収集できるよりも多くのガベージが作成される場合は、コレクタがそのサイクルを完了するまで Java スレッドが待機する間に休止が発生する。

パラレル

  • コレクション中にすべてのプロセッサを使用するため、メモリ スループットが最大になる。

  • -server オプションを指定して実行する場合 (デフォルトの動作) のデフォルト ガベージ コレクタ。

  • 「処理を停止」するために、処理中の休止時間が長くなることがある。

ガベージ コレクタを選択するためのマトリックス

表 3-3 は、ユーザの BEA JRockit JVM 実装に適したガベージ コレクタを決定するために使用できるマトリックスです。「状況」列で実装に合う状況を見つけて、「選択するガベージ コレクタ」列に示されたガベージ コレクタを選択してください。3 番目の列には、サポートされない (静的な) ガベージ コレクタにのほかに、ニーズに適したサポートされる (動的な) ガベージ コレクタを示します。

表 3-3 ガベージ コレクタを選択するためのマトリックス

状況

選択するガベージ コレクタ

動的なガベージ コレクタの場合

  • どんな長さでも休止は許容できない。

  • ギガバイトサイズのヒープを使用する。

  • 休止をなくすためにメモリ スループットを引き換えにできる。

  • メモリ容量の大きいシングル CPU マシンである。

シングルスペース コンカレント

-Xgcprio:pausetime

  • どんな長さでも休止は許容できない。

  • ギガバイトサイズのヒープを使用する。

  • 休止をなくすためにメモリ スループットを引き換えにできる。

  • シングルスペース コンカレントの場合よりもメモリ スループットを高くしたい。

  • BEA JRockit JVM の実装方法を考えると、他の 2 つの方式が十分かどうか確かではない。

世代別コンカレント

-Xgcprio:pausetime

  • 4 つの CPU を搭載したマシン、またはメモリ容量の大きいシングル CPU マシンを使用している。

  • 長い休止を時々許容できる。

  • メモリ スループットを最大にする必要がある。

パラレル

-Xgcprio:throughput

デフォルト ガベージ コレクタの設定

起動時に -Xgcprio または -Xgc を設定しない場合は、JVM モードとしてサーバサイド (-server、デフォルトのモード) とクライアントサイド (-client) のどちらを選択したかに基づいて、静的なガベージ コレクタがデフォルトのコレクタになります。これらはガベージ コレクタそのものを指定するオプションではありません。静的なコレクタを起動し、デフォルトの初期ヒープ サイズおよび最大ヒープ サイズを設定する JVM コンフィグレーション オプションです。表 3-4 は、これらの起動オプションを使ってガベージ コレクタを設定する方法を示しています。

表 3-4 JVM モードによって起動されるガベージ コレクタ

JVM モード

説明

-server

言うまでもなく BEA JRockit はサーバサイド JVM なので、-server オプションを使った場合の動作は BEA JRockit のデフォルトの動作と同じです。-server を選択すると、BEA JRockit は パラレル ガベージ コレクタ (-Xgc:parallel 設定に相当) を実行します。-server によるヒープ サイズとナーサリ サイズの設定については、『BEA JRockit JVM チューニング ガイド』の「最大ヒープ サイズの設定」と「ナーサリのサイズの設定」を参照してください。

-client

BEA JRockit を -client モードで起動すると、JRockit はクライアントサイド JVM として動作します。このモードは、ヒープが小さく、アプリケーションの実行時間が短いことを想定している場合に適しています。JVM の起動時に -client を選択すると、BEA JRockit は シングルスペース コンカレント ガベージ コレクタ (-Xgc:singlecon 設定に相当) を実行します。-client によるヒープ サイズとナーサリ サイズの設定については、『BEA JRockit JVM チューニング ガイド』の「最大ヒープ サイズの設定」と「ナーサリ サイズの設定」を参照してください。


 

-server オプションと -client オプションの使い方の詳細については、「BEA JRockit JVM の起動とコンフィグレーション」を参照してください。

 


ガベージ コレクタのオーバーライド

-Xgcprio を設定すると、 -server-client に関連するすべての設定がオーバーライドされます。-Xgc を設定すると、-Xgcprio -server、および -client がオーバーライドされます。

 


ガベージ コレクションのアクティビティの表示

ガベージ コレクションのアクティビティを観察するには、以下のいずれかのオプションを使用します。これらのオプションを使用すると、選択したガベージ コレクタの効果を評価して、必要なチューニング方法を判断することができます。

この 2 つのオプションを組み合わせると、アプリケーションのメモリの動作をよく調べることができます。

-java -Xgcreport -Xgcpause myClass

 


スレッドローカル割り当て

スレッドローカル割り当ては、オブジェクト割り当ての競合を取り除き、ヒープでメモリの割り当てを行うスレッド同士を同期する必要性を軽減します。また、異なる CPU 上で動作する 2 つのスレッドが同じメモリ ページに同時にアクセスするリスクが減るため、マルチ CPU システムでキャッシュのパフォーマンスが向上します。

スレッドローカル割り当てはスレッドローカル オブジェクトと同じではありませんが、2 つの用語は混同されやすくなっています。スレッドローカル割り当ては、オブジェクトが 1 つのスレッドからのみアクセスされる (つまり、スレッドローカル オブジェクトである) かどうかを決定するものではありません。スレッドローカル割り当てとは、他のスレッドが新しいオブジェクトを作成できない独自の領域をスレッドに持たせることを意味します。ただし、スレッドがその領域に作成するオブジェクトには、他のスレッドからもアクセスできます。

 

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