Java テクノロジ システムの自動メモリ管理の最も基本的な目標は、オブジェクトへのメモリの自動割り当てと、オブジェクトに割り当てられたメモリの自動的なリサイクルという 2 つの問題を自動的に解決することです。
1. 概要
オブジェクトのメモリ割り当ては、概念的にはヒープ上に割り当てられる必要があります (実際には、ジャストインタイム コンパイル後に間接的にスカラー型に逆アセンブルされることもあります)スタック上に割り当てられます)。クラシック世代の設計では、通常、新しいオブジェクトは若い世代に割り当てられますが、まれに (オブジェクト サイズが特定のしきい値を超えるなど)、古い世代に直接割り当てられることもあります。オブジェクト割り当てのルールは固定されていません。「Java 仮想マシン仕様」では、新しいオブジェクトの作成と保存の詳細は規定されていません。これは、仮想マシンが現在使用しているガベージ コレクタと仮想マシンのメモリ関連機能によって決まります。 . パラメータ設定。
多くの場合、オブジェクトは新世代 Eden 領域に配置されます。 Eden 領域に割り当てられる十分なスペースがない場合、仮想マシンはマイナー GC を開始します。
1. Eden 領域に十分なスペースがある場合
仮想マシンのパラメーター
-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
パラメーターの説明
2MB のサイズを 3 つと 4MB のサイズを 1 つ割り当ててみます。 size オブジェクトの実行時、Java ヒープ サイズは 3 つのパラメータ -Xms20M、-Xmx20M、および -Xmn10M によって 20MB に制限され、拡張できません。10MB は新しい世代に割り当てられ、残りの 10MB は古い世代に割り当てられます。世代。 -XX:Survivor-Ratio=8 は、新世代の Eden エリアと Survivor エリアのスペース比が 8:1 であることを決定します。
package com.xiao.test.Test; public class test { private static final int _1MB = 1024 * 1024; public static void main(String[] args) { byte[] byte1,byte2,byte3; byte1 = new byte[2 * _1MB]; byte2 = new byte[2 * _1MB]; byte3 = new byte[2 * _1MB]; } }
2. Eden 領域に十分なスペースがない場合
仮想マシンのパラメータは同じです
package com.xiao.test.Test; public class test { private static final int _1MB = 1024 * 1024; public static void main(String[] args) { byte[] byte1,byte2,byte3,byte4; byte1 = new byte[2 * _1MB]; byte2 = new byte[2 * _1MB]; byte3 = new byte[2 * _1MB]; byte4 = new byte[3 * _1MB]; } }
明らかにマイナー GC
1. ラージ オブジェクトとは何ですか?
ラージ オブジェクトとは、大量の連続メモリ領域を必要とする Java オブジェクトを指します。最も一般的なラージ オブジェクトは、多数の要素を含む長い文字列または配列です。
2. Java 仮想マシンで大きなオブジェクトを避けるべき理由
スペースを割り当てるとき、明らかに大量のスペースがある場合、ガベージ コレクションが事前にトリガーされる可能性があります。連続したスペースのみを使用して配置できます。オブジェクトをコピーする場合、オブジェクトが大きいと、メモリ コピーのオーバーヘッドが高くなります。
3. 大きなオブジェクトが古い世代に直接入る利点
Eden 領域と 2 つの Survivor 領域の間でのコピーを行ったり来たりすることを回避します。これにより、大量のメモリ コピー操作が発生します (HotSpot仮想マシンは -XX : PretenureSizeThreshold パラメータを提供し、設定値より大きいオブジェクトが古い世代で直接割り当てられることを指定します)。
1. 仮想マシンは、オブジェクトが長期的に存続するかどうかをどのように判断しますか?
メモリをリサイクルする場合、どの生き残ったオブジェクトを新しい世代に配置し、どの生き残ったオブジェクトを古い世代に配置するかを決定できなければなりません。これを行うために、仮想マシンはオブジェクトごとにオブジェクト経過時間 (Age) カウンターを定義し、オブジェクト ヘッダーに保存します。
2. オブジェクトの年齢増加と古い世代への昇格のプロセス
オブジェクトは通常、エデン領域で生まれます。最初のマイナー GC の後もまだ存続し、生存者、オブジェクトは生存者スペースに移動され、オブジェクトの年齢は 1 歳に設定されます。オブジェクトが Survivor 領域のマイナー GC を生き残るたびに、オブジェクトの年齢は 1 年ずつ増加し、一定の年齢 (デフォルトは 15) に達すると、古い世代に昇格します。古い世代に昇格するオブジェクトの存続期間のしきい値は、パラメーター -XX: MaxTenuringThreshold を通じて設定できます。
3. 寿命の長いオブジェクトが古い世代に入る理由
新しい世代のガベージ コレクション アルゴリズムがマーク コピー アルゴリズムであることは誰もが知っています。新しい世代にも保存されている場合、コピーのオーバーヘッドが増加するという問題が発生します。したがって、特定の年齢のしきい値を超えるオブジェクトを古い世代に配置することで、ガベージ コレクション中に新しい世代にかかる圧力を軽減できます。
さまざまなプログラムのメモリ状態に適切に適応するために、HotSpot 仮想マシンはオブジェクトの経過時間が -XX に達する必要があるとは限りません。古い世代では、Survivor 空間内の同じ年齢のすべてのオブジェクトのサイズの合計が Survivor 空間の半分より大きい場合、年齢がこの年齢以上のオブジェクトは、 -XX:MaxTenuringThreshold で必要な年齢を待たずに、古い世代に直接入ることができます。
1. スペース割り当て保証の内容
マイナー GC が発生する前に、仮想マシンはまず、古い世代で使用可能な連続スペースの最大値が、新しい世代のすべてのオブジェクトの合計スペースより大きいかどうかを確認する必要があります。この条件が true の場合、今回はマイナー GC を実行できます。安全を確保します。確立されていない場合、仮想マシンはまず、-XX:HandlePromotionFailure パラメータの設定値が保証失敗を許可するかどうかを確認し、許可されている場合は、古い世代で使用可能な最大連続領域が次の値より大きいかどうかを引き続き確認します。古い世代にプロモートされるオブジェクトの平均サイズ。それより大きい場合は、マイナー GC が試行されますが、今回はマイナー GC は危険です。小さい場合、または -XX: HandlePromotionFailure 設定によりリスクが許容されない場合、その場合、代わりにフル GC が実行されます。
2.「冒険」のリスクとは何ですか?
前述したように、新世代ではコピー収集アルゴリズムが使用されますが、メモリ使用量の都合上、Survivor スペースの 1 つだけが使用されます。は循環バックアップとして使用されるため、マイナー GC 後も多数のオブジェクトがまだ存続している場合、最も極端なケースでは、新しい世代のすべてのオブジェクトがメモリのリサイクル後も存続しており、古い世代は割り当て保証を実行する必要があり、オブジェクトは遺族が対応できないものは直接老人世代に送られるというもので、生命におけるローン保証と似ています。旧世代でそのような保証を行うには、旧世代自体にこれらのオブジェクトを収容できる空き領域がまだ残っていることが前提となりますが、実際のメモリのリサイクルが完了するまでは、このリサイクルでどれだけのオブジェクトが生き残るかは明確にわかりません。以前の各リサイクルで古い世代に昇格されたオブジェクト容量の平均サイズが経験値として使用され、古い世代の残りのスペースと比較され、より多くのスペースを解放するためにフル GC を実行するかどうかが決定されます。古い世代。
3. 保証を開始する必要がありますか?
比較のために過去の平均を取ることは、実際にはまだ確率に基づいた解決策です。つまり、特定のマイナー GC が生き残った後のオブジェクトの数が突然増加し、過去の平均よりもはるかに高い場合です。 、それでも保証が失敗したことになります。保証障害が発生した場合は、フル GC を正直に再開始する必要があるため、一時停止時間が非常に長くなります。保証が失敗した場合に円が最大になりますが、フル GC が頻繁になりすぎるのを避けるために、通常は -XX: HandlePromotionFailure スイッチがオンになります。
以上がJava 仮想マシンにおけるメモリ割り当てとリサイクル戦略の分析例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。