JVMの詳細な説明 - メモリ構造

メモリ構造

ここに画像の説明を挿入

1. ランタイムデータエリア

Java 仮想マシンは、Java プログラムの実行中に管理メモリをさまざまなデータ領域に分割します. さまざまな領域はさまざまな機能を担当し、独自のライフサイクルを持っています. これらの領域はまとめて実行時データ領域と呼ばれます.

スレッドのプライベートと共有の観点から:

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

スレッド共有:ヒープ、メソッド領域

スタックはランタイムの単位であり、ヒープはストレージの単位です

スタックは、プログラムの実行中の問題、つまり、プログラムの実行方法やデータの処理方法を解決します。ヒープは、データ ストレージの問題、つまりデータをどこにどのように配置するかという問題を解決します。


2. 仮想マシン スタック

機能: 仮想マシン スタックは Java スタックとも呼ばれ、主に Java プログラムの実行を管理し、ローカル変数とメソッドの部分的な結果を保存し、メソッドの呼び出しと戻りに参加します。

各スレッドには独自のスタックがあります. スタック内のデータはスタック フレームの形式で存在します. スレッド上で実行される各メソッドには, 対応する独自のスタック フレームがあります. メソッドが呼び出されるとスタック フレームがプッシュされます.メソッドが終了するとポップされます。

スタックフレームの内部構造

  • ローカル変数テーブル

主に、メソッド本体で定義されたメソッド パラメーターとローカル変数を格納するために使用されます (基本的なデータ型とオブジェクト参照を含む)。

  • オペランド スタック

主に計算処理の中間結果を保存するために使用され、同時に計算処理中の変数の一時的な格納スペースとしても使用されます.メソッドの実行中に、バイトコード命令に従って、データを書き込みまたはデータを抽出しますオペランド スタックから、つまり、スタックにプッシュし、スタックを取得します。

  • 動的リンク

ランタイム定数プールを指すメソッド参照

When a Java source file is compile into a bytecode file, all variable and method references are stored as symbolic references in the constant pool of the Class file. 動的リンクの機能は、これらのシンボリック参照を呼び出しメソッドへの直接参照に変換することです

  • メソッドリターンアドレス

呼び出しメソッドを格納するために使用される PC レジスタの値

メソッドの終了には、通常の実行、例外、および異常終了の 2 つの方法があります。

  • いくつかの追加情報

プログラムのデバッグをサポートする情報など、Java 仮想マシンに関連する追加情報を伝えます。


3.ネイティブメソッドスタック

ネイティブ メソッド スタックは、Java が非 Java コード、つまりNative Methodネイティブ メソッドを呼び出すためのインターフェイスです。

役割: オペレーティング システムと対話するために、Java アプリケーションは、配列をコピーするときにシステム コピーを使用するなど、基盤となるシステムのサポートに依存する必要がある場合があります。


4. プログラムカウンター

プログラムカウンタは、現在のスレッドによって実行されるバイトコードの行番号インジケータと見なすことができる小さなメモリ空間であり、実行される命令コードである次の命令を指すアドレスを格納します。

機能: CPU がスレッドを切り替えるとき、JVM はスレッドが次に実行する必要があるバイトコード命令を知る必要があり、次の命令のアドレスは PC プログラム カウンターに格納され、各スレッドの実行の進行状況は異なり、スレッドが異なる独自の PC プログラムカウンターが必要です。


5.ヒープ

ヒープは、Java 仮想マシンによって管理されるメモリの最大部分であり、すべてのスレッドによって共有されます。ヒープはオブジェクト インスタンスを格納するために使用され、ほとんどすべてのオブジェクト インスタンスとデータはここにメモリが割り当てられます。

ヒープはガベージ コレクションのメイン領域でもあり、ガベージ コレクションを効率的に実行するために、仮想マシンはヒープ メモリを論理的に 3 つの領域に分割します。

  • 新世代:新しく作成されたオブジェクトと特定の年齢に達していないオブジェクトを格納します
  • 古い世代:長い間使用されてきたオブジェクト、古い世代のメモリが大きい
  • メタスペース(JDK1.8 より前は永久生成と呼ばれていました): 一部のメソッドに一時オブジェクトを格納します

Java 仮想マシンの仕様では、Java ヒープは、ディスク領域と同様に、論理的に連続している限り、物理的に不連続なメモリ空間に配置できると規定しています。実装されると、固定サイズまたはスケーラブルにすることができます. 主流の仮想マシンはスケーラブルです (-Xmxおよびによって-Xms制御されます). インスタンスの割り当てがヒープ内で完了せず、ヒープを拡張できなくなった場合、例外が発生しますOutOfMemoryError.

-Xmx: ヒープの開始メモリ。デフォルトの初期化サイズはコンピュータ メモリ/64 です。

-Xmx: ヒープの最大メモリ。デフォルトの初期化サイズはコンピュータ メモリ/4 です。


6.メソッドエリア

メソッド領域はJVM仕様で定義された概念であり、クラス情報、定数プール、静的変数、JITコンパイルされたコードなどのデータを格納するために使用されます.永続的な生成は、Hotspot仮想マシンによるメソッド領域の実装です. (JDK8以降はメタスペースに変更)

JDK8以前はpermanent世代でメソッド領域を実装していましたが、permanent世代には-XX:MaxPermSize ​上限があり、設定しなくてもデフォルトのサイズがあるため、メモリオーバーフローしがちでした。JDK7では、永続世代に配置された文字列定数プールと静的変数が削除され、ヒープに保存されます.JDK8では、永続世代がキャンセルされ、代わりにローカル・メモリーに実装されたメタスペースが使用されます.型情報、フィールド、メソッド、および定数は、ローカル メモリのメタスペースに格納されます。


7. ランタイム定数プール

実行時定数プールはメソッド領域の一部です. 効果的なclassバイトコード ファイルには, クラスのバージョン情報, フィールド, メソッド, インターフェイスなどの記述情報だけでなく, さまざまなリテラルや型へのシンボリック参照を格納するための定数プール テーブルも含まれています. 、フィールド、およびメソッド。これらは、クラスがロードされた後にメソッド領域のランタイム定数プールに格納されます。

クラスファイル定数プールと比較したランタイム定数プールのもう 1 つの重要な機能はダイナミズムです. Java 言語では、コンパイル時にのみ定数を生成する必要はなく、新しい定数も実行時にプールに入れることができます.

例: intern()String クラスのメソッドの場合、文字列定数プールに対応するリテラルがあればメソッドはそのリテラルのアドレスを返し、存在しない場合は対応するリテラルを作成してランタイム定数プールに入れます。 、リテラル数量アドレスを返します。


8. メモリオーバーフローとメモリリーク

メモリ オーバーフローOutOfMemory、プログラムによって要求されたメモリが、JVM が提供できるメモリ サイズを超え、メモリ オーバーフロー、主にヒープ メモリ オーバーフローが発生します。

メモリ リークMemory Leak、割り当てられたメモリを解放できず、仮想マシンがメモリを再び使用できない


9.ヒープオーバーフロー

The heap is used to store object instances. オブジェクトが継続的に作成され、ガベージ コレクションを回避するために GC ルートからオブジェクトへの到達可能なパスがある限り、オブジェクトの数が増えるにつれて、プログラムが必要とするメモリ領域は、 JVM によって割り当てられたメモリ領域により、OOM プログラムがクラッシュします (たとえば、while 無限ループで常に新しいインスタンスが作成されます)。

ヒープ OOM の場合:

  • ヒープのメモリ サイズが正しく設定されていません
  • プログラムにメモリ リークの問題があるか、メモリを占有して時間内に解放できないアプリケーションに多数のオブジェクトがあります。

解決:

  • -Xms -Xmx ​ヒープのメモリ サイズを変更する
  • メモリ監視ソフトウェアを使用して、プログラム内のリークされたコードを見つける

オンライン審査方法:

  1. メモリの取得dump文件(1.例外がJVMトリガーされたときに自動的に生成されるスタートアップ パラメーターを構成する 2.ツールを使用して生成する)OOMjmap
  2. MAT ツールを使用した分析dump文件
    • メモリ リークの場合は、GC Rootsリークしたオブジェクトの参照チェーンを確認し、クラス情報と参照チェーン情報からコードの場所を特定して解決できます。
    • ヒープ スペースの割り当てはビジネス ニーズを満たすのに十分ではありません。ヒープ メモリ スペースを増やしてください

‍参照
記事:
‍1. https://pdai.tech/md/java/jvm/java-jvm-struct.html
2. https://blog.csdn.net/weixin_45629285/article/details/128050932

おすすめ

転載: blog.csdn.net/qq_52595134/article/details/129268459