この記事は JVM のメモリ領域の解析とガベージ コレクションに関するものです (写真とテキスト)。必要な方は参考にしていただければ幸いです。
1. JVM の概要
JVM、正式名は Java Virtual Machine、つまり Java 仮想マシンです。プログラミング言語として Java で記述されたアプリケーションは、JVM 上で実行されます。 JVM は、コンピュータのさまざまな機能を実際のコンピュータ上でシミュレートすることで実現される、架空のコンピュータの仕様です。 Java の非常に重要な特徴はプラットフォームからの独立性であり、JVM はこの特徴を実現するための鍵となります。
JVM によるプログラムの実行は、主に 2 つのステップに分かれています。最初のステップはコンパイルです。つまり、.java ソース ファイルが .class バイトコード ファイルにコンパイルされます。2 番目のステップは解釈です。 JVM はバイト コード ファイルを解釈して実行します。 2 つのステップのフローチャートを次の 2 つの図にそれぞれ示します。
2. JVM メモリ領域
JVM システム全体は 2 つのサブシステムに分かれています。 1 つ目は ClassLoader で、その機能は作成されたクラスを JVM にロードすることです。 2 つ目は実行エンジンで、コンパイルされたバイトコード ファイルの解釈と実行を担当します。前述の実行エンジンは 2 つの部分に分かれており、最初の部分はランタイム データ領域であり、JVM のメモリに相当します。2 番目の部分はローカライズ インターフェイスであるネイティブ インターフェイスです。 、主に他の非 Java プログラムを実行するために使用される、プログラミング言語で書かれたプログラム。
ポイントは前者のランタイムデータ領域で、メソッド領域(メソッド領域)、ヒープ(ヒープ)、VMスタック(仮想マシンスタック)、プログラムカウンタレジスタ(プログラムカウンタ)の5つの部分に分かれています。 )、ネイティブ メソッド スタック。最初の 2 つのスレッドは共有され、後の 3 つのスレッドは分離されます。以下の図に示すように:
要約すると、JVM はメソッド領域 (メソッド領域) とヒープ (ヒープ) を割り当てます。最初に実行されると、JVM はスレッドに遭遇するたびに、プログラム カウンター (プログラム カウンター)、VM スタック (仮想マシン スタック)、およびネイティブ メソッド スタック (ローカル メソッド スタック) をスレッドの終了時に割り当てます。ローカル メソッド スタック (メソッド スタックとプログラム カウンタによって占められていたメモリ空間) も解放されます。データ領域がスレッド共有とスレッド分離に分割されている理由もこれです。3 つのスレッド分離領域のライフ サイクルは、それが属するスレッドのライフ サイクルと同じであり、スレッド共有領域はスレッドのライフ サイクルと同じです。これは、実行中の Java プログラムのライフサイクルに影響するため、これもシステム ガベージです。これは、リサイクルがスレッド共有領域でのみ発生する理由です (実際、ほとんどの仮想マシンでは、ヒープ上でリサイクルが発生します)。メモリ オーバーフロー例外については、次の図に示します。
#1. メソッド領域 メソッドエリアには定数プールと静的フィールドが含まれます。ロードしたクラスの情報(名前、修飾子など)、クラスの静的変数、クラスの定数、クラスのフィールド情報、クラスのメソッド情報を格納します。開発者が Class オブジェクトの getName や isInterface などのメソッドを通じてプログラム内の情報を取得すると、これらのデータはメソッド領域から取得されます。 2. ヒープ (ヒープ) ヒープは、JVM によって管理される最大のメモリ部分であり、ほとんどすべてのオブジェクトがこの領域に存在すると考えられます。 Java の new では、オブジェクトのメモリがここに割り当てられ、ヒープ内のオブジェクトのメモリは GC がリサイクルされるまで待機する必要があります。 3. プログラム カウンタ レジスタ (プログラム カウンタ) プログラム カウンタは、現在のスレッドによって実行されるバイトコードの行番号を示すインジケータです。が動作している場合、カウンターの値を変更することで実行する次のバイトコード命令を選択します。分岐、ジャンプ、ループなどの基本的な機能はすべてこれに依存して実装されます。 4. VM スタック (仮想マシン スタック) 仮想マシン スタックは、Java メソッドの実行時にスタック フレーム (スタック フレーム) を作成します。フレームは、ローカル変数テーブル (基本データ型、オブジェクト参照など)、オペランド スタック、ダイナミック リンク、メソッドの戻りアドレス、およびいくつかの追加情報を格納するために使用されます。 5. ネイティブ メソッド スタック この領域は、仮想マシン スタックが Java メソッドを実行するために仮想マシンにサービスを提供することと、ローカル メソッドを実行することを除いて、仮想マシン スタックと非常によく似た役割を果たします。 stack は、使用されるネイティブ オペレーティング システム (Native) メソッドを提供します。
3. JVM ガベージ コレクション
JVM の GenerationalCollecting (ガベージ コレクション) 原理は、オブジェクトを若い世代 (Young)、古い世代 (Tenured)、および永続的な世代 (Perm) に分割し、異なるライフ サイクルを持つオブジェクトに対して異なるアルゴリズムを使用することです。
通常、JVM メモリのリサイクルは常にヒープ (ヒープ) メモリのリサイクルを指します。実際、ヒープ (ヒープ) 内のコンテンツのみが動的に割り当てられるため、上記のオブジェクトの若い世代と古い世代の両方が参照されます。 JVM の Heap (ヒープ) 領域であり、永続世代は Heap (ヒープ) に属さない前述の Method 領域 (メソッド領域) です。
#1. 若い世代
#このスペースはほとんどが小さなオブジェクトであり、頻繁にリサイクルされます
若い世代のヒープスペースのガベージコレクションは非常に頻繁に行われるため、そのガベージコレクションアルゴリズムはリサイクル効率にさらに注意を払います
2 . 古い世代
若い世代のヒープ領域内の存続期間の長いオブジェクトは、古い世代のヒープ領域に (おそらく永久に) 転送されます。スペースは通常より大きいです。若い世代のヒープスペースは大きく、スペースの増加率は遅いです。
JVM ヒープスペースのほとんどが古い世代に割り当てられているため、ガベージコレクションアルゴリズムをさらに強化する必要があります。このアルゴリズムは、低ガベージ密度のヒープ領域を処理できる必要があります。
#3. 永続的な世代# は、VM のメタデータを保存します。変数 これら 3 世代のヒープ スペースが不足しているか、新しいリクエストに割り当てる十分なスペースがない場合、ガベージ コレクション メカニズムが有効になります。 。ガベージ コレクションには、マイナー GC とフル GC の 2 種類があります。若い世代のヒープ領域がいっぱいになると、コレクションがトリガーされ、残っているオブジェクトが古い世代のヒープ領域に移動されます。旧世代のヒープ領域がいっぱいになると、オブジェクト ヒープの全範囲をカバーする完全なコレクションがトリガーされます。
以上がJVMメモリ領域の解析とガベージコレクション(画像とテキスト)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。