JVM:メモリの割り当てと回復の戦略

最終的に自動メモリ管理に提唱したJavaテクノロジー・システムは、自動化に起因することができる2つの問題を解決:オブジェクトのメモリの割り当てと回復に反対するためにメモリ割り当てを。

メモリ割り当てオブジェクト、話すの一般的な方向に、ヒープに割り当てられている(しかし、おそらくスタック上のスカラー型と間接配信後JITコンパイラを突破)あなたが開始した場合、主な目的は、エデンエリアの新しい世代に割り当てられていますローカルスレッド割り当てバッファは、優先順位がTLABにスレッドが割り当てられます。稀なケースでは、直接古い時代ではなく、100%の固定割り当てルールに割り当てることができ、詳細はガベージコレクタの組み合わせを設定することとなっている現在の使用、ならびにメモリ関連のパラメータ内の仮想マシンに依存します。

次に、我々は、最も一般的なメモリ割り当てルールのいくつかを説明しますと、それらのルールでコードを検証します。

エデンに優先配分オブジェクト
ほとんどの場合、エデンエリアの新世代内のオブジェクトの割り当て。エデン領域が割り当てられた十分なスペースがない場合、仮想マシンはマイナーGCを起動します。

仮想マシンは、-XXを提供:PrintGCDetailsはコレクターログパラメータ、印刷は、仮想マシンのメモリ回復ログを伝える際に、ガベージコレクションの動作、および各地域のプロセスが終了で出力電流のメモリ割り当て。実際のアプリケーションでは、メモリ回復ログは、一般的なツールをロギングすることで、分析のためにファイルに印刷されています。

= 1024×1024プライベート静的最終int型_1MB。

/ **
* VM参数:-verbose:GC -Xms20M -Xmx20M -Xmn10M -XX:+ PrintGCDetails -XX:SurvivorRatio = 8
* /
パブリック静的ボイドtestAllocation(){
バイト[] allocation1、allocation2、allocation3、allocation4に。
allocation1 =新しいバイト[2 * _1MB]。
allocation2 =新しいバイト[2 * _1MB]。
allocation3 =新しいバイト[2 * _1MB]。
allocation4に=新しいバイト[4 * _1MB]; //出现一次マイナーGC
}
运行结果:

 

コード上testAllocation()メソッド、および2メガバイト3のサイズは、実行時に4MBの割り当てサイズのオブジェクトを試みる-XMs20M、-XMx20M、-Xmn10M 3つのパラメータは、Javaヒープ・サイズの20メガバイトを制限拡張することができませんこれは、古い時代の残りの部分に割り当てられた10メガバイト、10メガバイトの新しい世代に割り当てられています。-XX:SurvivorRatio = 9新世代領域における空間の割合を決定し、サバイバーエデンゾーンは8:出力の結果から、1はっきりと見ることができる「エデンスペース8192Kを、空間1024Kから、空間1024Kの」情報、新世代の9216キロバイト(総容量エデン領域+1サバイバー領域)のために利用可能な全スペース。

ステートメントが実行されたときに割り当てがマイナーGC一度testAllocationを()オブジェクトallocation4に発生し、GCは、6651キロバイト148キロバイトの新しい世代に結果であり、一方、総メモリフットプリントとほとんど減少(allocation1ため、allocation2、allocation3 3つのオブジェクト)仮想マシンはほとんどリサイクル見つかったオブジェクトで、生きています。これが起こる理由は、私は、エデンは6MVを占領されていることがわかったときにGCがメモリを割り当てallocation4にすることで、残りのスペースは、メモリに必要なallocation4に4MBのを割り当てることが十分ではなく、したがって、マイナーGCが発生します。また、仮想マシンの中に発見されたGCは、すべてのオブジェクト・スペース・サバイバーを(サバイバースペースのみ1MBのサイズである)に適合しない3つの2メガバイトのサイズを持っているので、私は、古い年、外出先に進めるために保証メカニズムを割り当てることによって転送しなければなりませんでした。

allocation4のオブジェクトがエデンでの円滑な流通を4MB、そのプログラムの実行結果は、エデンは4メガバイト(allocation4のが占有されている)、サバイバーのアイドルを占めて終了したGCの終了後、古い年は(allocation1、allocation2、allocation3占有によって)占有されています。GCログによってこれを確認することができます。

注意:マイナーGC繰り返し異なっている何のフルGCと呼ば?

新世代GC(マイナーGC):Javaオブジェクトのほとんどは非常に頻繁に、オフの特性Chaoshengの夜ので、マイナーGCを持っているので、新世代のガベージコレクションアクションで場所を指し、通常は比較的速いスピードを回復します。
古いのGC(メジャーGC /フルGC) : GCは、古い時代に発生することが意味し、それが収集ポリシーパラレル掃気コレクターに直接であることが多い少なくともマイナーGCの1(ただし、絶対的ではないが伴う主なGCは、あったが、ポリシー選択プロセスの主なGCの行為)。主なGCの10倍以上のマイナーGCの速度よりも一般的に遅いです。
直接旧への大規模なオブジェクトをだ
、いわゆるラージオブジェクトは、Javaオブジェクトを参照する連続したメモリ空間の多くを必要と、最も典型的には、(バイト[]配列は、ラージオブジェクトの典型的なものである)、大きなオブジェクトと長い文字列配列の一種です。仮想マシンのメモリ割り当てのラージ・オブジェクトは、Java仮想マシンのための悪いニュースは、(道の文句で、悪いニュースは「オフ夜に向けて学生」のグループと「短命ラージオブジェクト」、書かれた手順を満たしているよりも多くの大きなオブジェクトに遭遇しました時間は十分な連続スペースを得るためにメモリ空間が多いとき、多くの場合、簡単にトリガーされる先行ガベージコレクションの大きなオブジェクトにつながる、)避けるべきで、「配置」彼ら。

オブジェクトは、古い時代に直接割り当てられた設定値よりも大きくなるように、PretenureSizeThresholdパラメータ:仮想マシンは、-XXを提供しています。目的は、エデンと2つのサバイバー領域の間の領域で発生したメモリコピー(メモリを集める新世代を使用してコピーアルゴリズム)、大量のを避けるためです。

最終的な静的int型_1MB =プライベート1024 1024 *;

/ **
* VMパラメータ:-verbose:GC -Xms20M -Xmx20M -Xmn10M -XX:+ PrintGCDetails -XX:= 8 SurvivorRatio
* -XX:PretenureSizeThreshold = 3145728
* /
パブリック静的な無効testPretenureSizeThreshold(){
バイト[]割り当て、
割り当て=新しい新しいバイト[* _1MB 4。]; //古い時代に直接割り当て
}
結果の実装:

 

上記のコードtestPretenureSizeThreshold()メソッドを実行した後、我々は少しエデンのスペースが使用されていない見て、宇宙の古い時代の10メガバイトを直接古い4MBの年に割り当てられたオブジェクトの割り当てでは40%、で使用されて、これがためでありますPretenureSizeThresholdが(3145728であり、このパラメータは、直接書込み3メガバイトとして-Xmxパラメータようにすることはできません)3メガバイトに設定され、従ってターゲットを上回る3メガバイト直接古い時代に配置されます。このパラメータを知らないだけで2つのコレクタ効果的なシリアルとParNew、パラレルスカベンジコレクタのPretenureSizeThresholdパラメータに注意してください、パラレルスカベンジコレクタは、一般的に設定する必要はありません。あなたは、このパラメータを使用しなければならない状況が発生した場合は、コレクタ組み合わせParNewプラスCMSを検討します。

歳を入力するオブジェクトの長期生存
メモリを管理する世代のコレクションを使用して仮想マシンのアイデア以来は、メモリの回復は、古い時代に置かれるべきであるオブジェクトの新しい世代、上に配置する必要があるオブジェクトを識別できなければなりません。これを行うには、各オブジェクトの仮想マシンは、対象年齢(年齢)カウンタを定義します。オブジェクトがエデンで生まれ、最初のマイナーGC後にまだ生きている、とサバイバーを収容することができたならば、それはサバイバースペースに移動され、そしてオブジェクトが1に設定されています。あらゆる分野での生存者のオブジェクトが1歳のマイナーGC、年齢、増加、ある程度の彼の年齢(デフォルトは15歳)「を介して取得」、彼らは古い時代に昇格されます。MaxTenuringThreshold設定:オブジェクト昇格の老齢しきい値は、パラメータは、-XXすることができます。

最終的な静的int型_1MB =プライベート・1024×1024 *;

/ **
* VMパラメータ:。。-verbose:GC -Xms20M -Xmx20M -Xmn10M -XX:+ PrintGCDetails -XX:SurvivorRatio = -XX 8:MaxTenuringThreshold 1 =
* -XX:+ PrintTenuringDistribution
* /
@SuppressWarnings( "未使用")
公共の静的な無効testTenuringThreshold(){
バイト[] allocation1、allocation2、allocation3;
allocation1 =新しい新しいバイト[_1MB / 4]; // XXにの古い決定を入力するとき:MaxTenuringThresholdが設定
allocation2 =バイト新しい新規[* _1MB 4];
allocation3 =新しい新しいバイト[* _1MB 4。];
allocation3 = NULL;
allocation3 =新しい新しいバイト[* _1MB 4];
}
MaxTenuringThreshold = 1つのパラメーター実行結果で:

 

MaxTenuringThreshold = 1と-XX:このメソッドは、オブジェクトメモリ256キロバイトを必要allocatioin1 MaxTenuringThreshold = 15は、コードtestTenuringThreshold上記の2種類を行うために設けられている()メソッド、サバイバースペースを収容することができ、それぞれ-XXを試みます。MaxTenuringThreshold = 1は、オブジェクトが二GCはGC後のメモリの新世代になって非常にきれいが0キロバイト使用されています。そして、MaxTenuringThresholdは= 15、第2 GCが発生し、発生した入るときallocation1歳、allocation1オブジェクトである時間の後サバイバーは、スペースの新しい世代に残って、その後、新しい世代は、まだ404キロバイト占有しています。

動的オブジェクトの年齢決意
良く異なる条件プログラムメモリに適応するためには、仮想マシンは、年齢の要件の目的はプロモーション歳前にMaxTenuringThresholdに達して、常にではないが、同じ年齢、合計はスペースサバイバーサバイバースペース内のすべてのオブジェクトのサイズよりも大きい場合対象年齢の半分は、あなたが、直接要件の年齢MaxTenuringThresholdまで待つ必要が歳行くことはできません以上の年齢に等しいです。

= 1024×1024プライベート静的最終int型_1MB。

/ **
* VM参数:-verbose:GC -Xms20M -Xmx20M -Xmn10M -XX:+ PrintGCDetails -XX:SurvivorRatio = 8 -XX:MaxTenuringThreshold = 15
* -XX:+ PrintTenuringDistribution
* /
@SuppressWarnings( "未使用")、
公衆静的ボイドtestTenuringThreshold2(){
バイト[] allocation1、allocation2、allocation3、allocation4に。
allocation1 =新しいバイト[_1MB / 4]。// allocation1 + allocation2大于survivo空间一半
allocation2 =新しいバイト[_1MB / 4]。
allocation3 =新しいバイト[4 * _1MB];
allocation4に=新しいバイト[4 * _1MB];
allocation4に= NULL;
allocation4に=新しいバイト[4 * _1MB];
}
运行结果:

 

TestTenuringThreshold2は、上記のコード()メソッドを実行し、-XX設定:MaxTenuringThreshold = 15を、古い年は予想よりも高い6%増加した空間は、0%でサバイバーまだ動作結果を占領したでしょう、すなわち、allocation1、allocation2古い時代にオブジェクトを直接、そして15歳の厄年まで待てません。これらの2つのオブジェクトが一緒に512キロバイトに達している、と彼らは同じ年のルールサバイバースペースの半分に到達するために目標を達成するために、同じ年であるため。私達はちょうどあなたが別の古い年、外出先に昇格されることはないでしょう、オブジェクトの1 new演算子をコメントアウトする必要があります。

スペースの割り当てを保証
それはマイナーGCを発生する前に、この条件が満たされた場合の古い使用可能な最大連続した領域は、総容量の新世代内のすべてのオブジェクトよりも大きいかどうかをチェックするための仮想機会、そしてマイナーGCそれが安全であることを確実にします。満たされていない場合は、仮想機会がHandlePromotionFailureの設定が失敗したことを保証できるようにするかどうかを確認します。許可された場合、それは前の歳より大きいの古い最大利用可能な連続スペースがより大きい場合には、オブジェクトの平均サイズに昇進したマイナーGCにもかかわらず、マイナーGCを実施しようとするかどうかをチェックしていきます危険です。未満ならば、またはHandlePromotionFailureの設定がリスクを許可しない、それは完全なGC一度変更する必要があります。

以下は、「冒険」は、コレクションのアルゴリズムをコピーの新世代を使用して、前述のいずれかのリスクを取ることですが、メモリの使用率のために、バックアップとして回転させるために一つだけサバイバースペースを使用し、その際に多数のオブジェクトマイナーGCで後に説明状況はまだ生きている、あなたはサバイバーは、古い時代にオブジェクトを直接収容することができない、保証歳割り当てる必要が(最も極端なケースは、すべてのオブジェクトが生き残った後のメモリリコールの新世代ということです)。そして、このような保証をする歳に似た生活の中で融資保証は、そう、ガベージコレクションの実際の完了を明確に知られていないされるまで、これらのオブジェクトを保持し、どのように多くのオブジェクトの合計が生き残る残りのスペース自体は、古いがあることを提供しましたかつての古い経験として、オブジェクトの容量の回復値の平均サイズに昇格していた、そして残りのスペースは、それぞれがより多くのスペースの歳にするかどうかを決定するために、完全なGCを取る前歳と比較されます。

平均よりもはるかに高い生存期間マイナーGCの急激な増加、後のオブジェクトが、それはまだセキュリティの失敗につながる場合、つまり、実際にはまだ、動的確率の手段を平均比較(プロモーションの失敗をハンドル)。HandlePromotionFailure障害がある場合は、それが失敗した後のフルGCを再起動する必要がありました。セキュリティの失敗の時間の周りに円が最大であるが、ほとんどの場合、まだスイッチをHandlePromotionFailureます開いているが、あまりにも頻繁に全GCを避けるために、次のコードは、JDK 6アップデート24テストの以前のバージョンで実行するために参照してください。

= 1024×1024プライベート静的最終int型_1MB。

/ **
* VM参数:-Xms20M -Xmx20M -Xmn10M -XX:+ PrintGCDetails -XX:SurvivorRatio = 8 -XX:-HandlePromotionFailure
* /
@SuppressWarnings( "未使用")
パブリック静的ボイドtestHandlePromotion(){
バイト[] allocation1、 allocation2、allocation3、allocation4に、allocation5、allocation6、allocation7。
allocation1 =新しいバイト[2 * _1MB]。
allocation2 =新しいバイト[2 * _1MB]。
allocation3 =新しいバイト[2 * _1MB]。
allocation1 = NULL;
allocation4に=新しいバイト[2 * _1MB]。
allocation5 =新しいバイト[2 * _1MB]。
allocation6 =新しいバイト[2 * _1MB]。
allocation4に= NULL;
allocation5 = NULL;
allocation6 = NULL;
=新しい新しいバイトallocation7 [2 * _1MB];
}
HandlePromotionFailure = FALSEパラメータ実行結果は:

 

HandlePromotionFailureに結果を実行するために、真のパラメータを=:

 

JDK 6アップデート24の後、変化するであろう試験結果は、HandlePromotionFailureパラメータ空間は、仮想マシンの割当戦略保証に影響を与えないであろう、で観察されたOpenJDKのソース・コードの変更(以下のコードを参照)、ソースコードもHandlePromotionFailureパラメータを定義しているが、しかしすでに、もはやあなたのコードでそれを使用していません。6アップデート24 JDK後のルール変更は限り連続した領域老後の平均サイズは、オブジェクトまたは前のプロモーションの新世代の合計サイズよりも大きいと、それ以外の場合は完全なGCなり、マイナーGCになります。

 

おすすめ

転載: www.cnblogs.com/hyhy904/p/10954423.html