Java仮想マシンのガベージコレクションメカニズム、ヒープメモリの世代別ストレージ、クラスのロードとアンロード

==============================================

                                    1:メモリモデル

==============================================

 

スレッド共有領域:ヒープ(ヒープ)およびメソッド領域(メソッド領域)

スレッドプライベート:プログラムカウンター、Java仮想マシンスタック、ローカルメソッドスタック。

ヒープ(ヒープ):新しいオブジェクトの保管場所(過剰なストレージはメモリオーバーフローの原因になります)

メソッド領域:静的属性と定数を格納します(過剰なストレージはメモリオーバーフローの原因になります)

 

プログラムカウンター:現在のスレッドが実行する行または命令を記録するものとして理解できます。そのため、スレッドが切り替わったときに、実行は現在の命令から続行できます。

Java仮想マシン:スタックフレームを保存します。メソッドが呼び出されるたびに、スタックフレームが仮想マシンに配置されます。スタックに過度にプッシュすると、スタックがオーバーフローします(つまり、メソッド呼び出しレベルが深すぎます)。

ネイティブメソッドスタック:仮想マシンに似ていますが、このスタックはネイティブメソッドのスタックフレームを格納するために使用されます。

==============================================

                                    2:メモリモジュール分割

==============================================

 

[ 1:回復アルゴリズム----世代別収集アルゴリズム ]

        [ 到達可能性分析アルゴリズム ]オブジェクトを回復する必要があるかどうかマークするアルゴリズム

        オブジェクト参照は、参照チェーンをパスとして使用して相互に参照します。オブジェクトへの参照のチェーンがルートノード(GC Roots)のいずれにも接続されていない場合、このオブジェクトは役に立たないため、リサイクルする必要があります。いわゆるルートノード参照は、静的属性、定数属性、およびスタックフレーム参照です。また、ネイティブメソッドによって参照される変数(メンバー変数とは言わないでください)への参照もあります。これら4つへの参照がない場合は、オブジェクトが役に立たないことを意味します。

       

         オブジェクトのライフサイクルは、若い世代古い世代に分けられます。

------- 新生代複製アルゴリズムを採用します。(低オブジェクト生存率のアルゴリズム)

--------------------  複製アルゴリズム:メモリを2つに分割し、同じサイズの2つの領域に分割します。一度に使用される領域は1つだけです。この領域がほぼ使い尽くされると、この領域内のすべての残存オブジェクト(アクセシビリティ分析アルゴリズム)が別の領域にコピーされ、この半分の領域がクリアされます。毎回、半分の領域全体が回復されます。

                                           短所:毎回使用できるのはメモリ領域の半分だけであり、メモリ領域の使用率が低すぎる

                                            利点:効率が高く、毎回面積の半分しか回復しません。メモリの断片化の問題を考慮する必要はありません。コピー後に再配置されるため、残りの内部

                                                       保管スペースは完全かつ継続的に配置されます。

 

------- Old ageマーククリアアルゴリズムまたはマークソートアルゴリズムを使用(高いオブジェクト生存率に使用されるアルゴリズム)

-------------------- マーククリアアルゴリズム:到達可能性分析アルゴリズムを通じてリサイクルするオブジェクトをマークすると、マークされたオブジェクトはGCスレッドによってリサイクルされます。

                                           欠点1>効率の問題、マークと効率が明確でない

                                           短所2>  スペースの問題。クリアすると、不連続なメモリフラグメントが多数生成されます。後で大きなオブジェクトにメモリスペースを割り当てる場合、これらのメモリフラグメントでは十分なスペースを確保できないため、GCは再利用されます。                                      

-------------------- マーキング-ソートアルゴリズム:到達可能性分析アルゴリズムを介してリサイクルするオブジェクトをマークすると、マークされたオブジェクトはGCスレッドによってリサイクルされます。「マーカー除去アルゴリズム」の拡張版です。再利用可能なオブジェクトを直接クリーンアップせずに、残っているオブジェクトを片側に移動して、残っているすべてのオブジェクトがメモリ空間で連続的にソートされるようにします。次に、境界の外にある不要なオブジェクトを直接クリーンアップします。

                                           利点1>  は、メモリの断片化の問題を解決します

                                         

--------------------- [ Mark-Clear Algorithm ]サンプル画像

 

--------------------- [ Marking-Arrangement Algorithm ]サンプル画像

 

[ 2:ガベージコレクタ-回復メカニズム ]

ガベージコレクターは、リサイクルが必要なオブジェクトをスキャンします。このオブジェクトのfinalize()が呼び出されたことがないため、オブジェクトのfinalize()が呼び出されます。finalize()オブジェクトがルートノードに再接続された場合(オブジェクトを静的変数に割り当てるなど)、オブジェクトは現時点ではリサイクルされません。ただし、オブジェクトのfinalize()メソッドがすでに呼び出されている場合、finalize()は再度呼び出されず、オブジェクトは直接リサイクルされます。

[ 3:メモリの割り当てとリサイクル戦略 ]

1:パーティション

新生オブジェクトのメモリ割り当ては次のように分けられます:Eden  >  Survivor  > 高齢者領域    の   優先度は順次減少します

新しい領域: EdenとSurvivor(コピーおよび回復アルゴリズム)

古いエリア:古いエリア(マーキングの並べ替えとリサイクルアルゴリズム)

 

注:すべてのオブジェクトが最初に新しい領域に保存されるわけではありません。たとえば、オブジェクトが特に大きい場合、オブジェクトは直接古い領域に 入ります。

したがって、ラージオブジェクトの作成を回避すると、ガベージコレクターがトリガーしてガベージを事前に収集し、ラージオブジェクトを配置するための十分な連続スペースを提供します。

(Java仮想マシンは、パラメータを介してラージオブジェクトの境界を設定できます)。高齢者ゾーンに直接入れるだけではありません。

 

[ 2:メモリ領域でのオブジェクトの動き ]

<ルール1>    年齢カウンター。ガベージコレクターによってスキャンされるたびに、年齢は+1になります。Edenは1回掃引され、生き残った場合はSurvivor領域に移動し、Survivor領域が15回掃引された場合は古い領域に移動します。もちろん、これらの制限のパラメータは制御できます。

<ルール2>    年齢判定ルールは一意ではありません。Survivor領域で同じ年齢のすべてのオブジェクトが占めるメモリの合計がSurvivorスペースの半分より大きい場合、この年齢より古いオブジェクトは高齢者領域に移動されます。

<ルール3>

1>オブジェクトは最初、SurvivorのEden領域とFrom領域にのみ存在し、Survivorの "To"は空です。

2> GCの直後に、エデンエリア内のすべての生き残ったオブジェクトが "To"にコピーされ、 "From"エリアでは、生き残ったオブジェクトが年齢に応じて移動先を決定します。経過時間がしきい値に達したオブジェクトは古い世代に移動され、しきい値に達していないオブジェクトは「To」領域にコピーされます。

3>マイナーGCは、「To」領域がいっぱいになるまでこのプロセスを繰り返し、「To」領域がいっぱいになると、すべてのオブジェクトが古い世代に移動されます。

 

 

==============================================

                                    2:クラスローディング

==============================================

クラスのロードは、5つの主要なステップに分かれています。

1:ロード

1:このタイプのバイナリストリームを取得する(それぞれzip、ネットワーク(アプレット)、ランタイム生成(動的プロキシ))

2:このフローをメソッドに変換してデータ構造を実行する

3:メソッド領域でこのクラスのデータアクセスインターフェイスとしてこのクラスのClassオブジェクトを生成する

2:接続

              セグメンテーション:検証、準備、分析

検証:エンコーディングがUTF-8に準拠しているかどうか、定数タイプがサポートされているかどうかなどを確認します。

準備:メモリの割り当て、変数の初期化

解決策:仮想マシンは定数プールシンボル参照を直接参照に置き換えます

 

3:初期化】   

クラスローディングの最後のステップ

4:使用

使用はオブジェクトのプロパティを使用することです

5:アンインストール

アンインストール、参照プロセスが強制終了されたときに理解できます

 

クラスとクラスローダーの関係

2つのクラスが等しいかどうかを比較することは、2つのクラスが同じクラスローダーによってロードされた場合にのみ意味があります。それ以外の場合、2つのクラスが同じクラスファイルに由来し、同じ仮想マシンにロードされている場合でも、それらをロードするローダーが異なる限り、2つのクラスは等しくないはずです。

Javaはクラスが等しいかどうかを判別します(equals()メソッド、isAssignableFrom()メソッド、isInstance()メソッドが結果を返します)

 

Java仮想マシンの観点から見ると、ローダーは2種類しかありません。

1:クラスローダーを起動する

2:その他のクラスローダー

 

Javaデザイナが開発者に推奨するクラスローディングメカニズムは、次のとおりです。親の委任モデルは         、次の図に示すとおりです。


 

上の図は、先頭のスタートアップクラスローダーを除いて、親委譲モデル  示しています。他のローダーには、独自の親クラスローダーがあります。ここでの親子関係は、通常、統合された関係ではありませんが、複合関係を使用して親ローダーのコードを取得します。

 

[ 親の委任モデルの作業プロセス ]

        クラスローダーが読み込み要求を受け取ると、まずそれを完了するために親クラスに要求をスローします。これはローダーの各レベルに当てはまるため、最終的にすべての要求は最上位の起動クラスローダーに渡されます。親クラスローダーが読み込みタスクを完了できないことを報告すると、子クラスローダーはそれ自体で読み込みを試みます。

メリット

         このロードメカニズムには、優先順位の階層関係があります。クラスをロードしようとすると、そのクラスは最終的にトップスタートアップクラスローダーに渡され、プログラム内のクラスの一意性が保証されます。次に例を示します。たとえば、rt.jarに格納されているjava.lang.Stringをロードするには、最終的にトップスタートアップクラスローダーに委任されてロードタスクを完了するため、プログラム内の各クラスローダー環境にStringクラスが存在します。どちらも同じクラスです。逆に、親の委任モデルがない場合は、各クラスローダーがクラスを個別にロードし、java.lang.Stringを例に取り、各クラスローダーがStringクラスをロードすると、プログラム内に複数の異なるStringクラスが存在します。 、それは非常に混乱し、Javaプログラムの最も基本的な動作は保証されません。

 

 

 

 

おすすめ

転載: blog.csdn.net/Leo_Liang_jie/article/details/90379533