ホームページ  >  記事  >  Java  >  JVMの内部構造と動作仕組み

JVMの内部構造と動作仕組み

尚
転載
2020-06-16 16:23:282307ブラウズ

JVMの内部構造と動作仕組み

1. Java メモリ構成の概要: ヒープ非ヒープ(非ヒープ) )メモリ

公式声明によると、「Java仮想マシンにはヒープがあります。ヒープはランタイムデータ領域であり、すべてのクラスインスタンスと配列のメモリはここから割り当てられます。」 .

ヒープは、Java 仮想マシンの起動時に作成されます。" "JVM のヒープ外のメモリは、非ヒープ メモリ (非ヒープ メモリ) と呼ばれます。" JVM は主に 2 種類のメモリ (ヒープと非ヒープ ) を管理していることがわかります。

簡単に言えば、ヒープは Java コードにアクセスできるメモリであり、開発者用に予約されています。非ヒープは JVM が独自に使用するために予約されているメモリであり、メソッド領域、JVM 内部に必要なメモリです。処理または最適化 (JIT コンパイル済みコード キャッシュなど)、各クラス構造 (実行時定数プール、フィールド、メソッド データなど)、およびメソッドとコンストラクターのコードは非ヒープ メモリ内にあります。

#2. JVM メモリ領域モデル

JVMの内部構造と動作仕組み

1. メソッド領域 「永続世代」や「非ヒープ」とも呼ばれ、仮想マシンがロードするクラス情報、定数、静的変数を格納するために使用され、各スレッドで共有されるメモリ領域です。デフォルトの最小値は 16MB、最大値は 64MB です。-XX:PermSize および -XX:MaxPermSize パラメーターを使用してメソッド領域のサイズを制限できます。

実行時定数プール: これはメソッド領域の一部であり、その主な内容は JVM によるクラスのロードから得られます。

クラス ファイルには、クラスのバージョン、フィールド、メソッド、インターフェイスなどの記述情報に加えて、コンパイラによって生成されたさまざまなシンボル参照を格納するために使用される定数プールもあります。クラスがロードされた後、メソッド領域のランタイム定数プールに配置されます。

2. 仮想マシン スタック

は、Java メソッド実行のメモリ モデルを記述します: 各メソッドが実行されると、ストレージ用の「スタック フレーム」が作成されます ローカル変数テーブル(パラメータを含む)、操作スタック、メソッド出口、その他の情報。各メソッドの呼び出しから実行完了までの過程は、仮想マシンスタックにおいてスタックフレームがスタックにプッシュされてからスタックからポップアウトされるまでの過程に相当する。宣言サイクルはスレッドと同じであり、スレッドに対してプライベートです。

ローカル変数テーブルには、コンパイラに認識されるさまざまな基本データ型 (

booleanbytecharshort# #) が格納されます。 #, int, float, long, double)、オブジェクト参照 (オブジェクト自体ではなく参照ポインター)、うち 64 bits Long 型および double 型のデータはローカル変数 2 個分のスペースを占有しますが、その他のデータ型は 1 つのスペースのみを占有します。 ローカル変数テーブルに必要なメモリ空間は、コンパイル中に割り当てられます。メソッドを開始するときに、このメソッドがスタック フレームに割り当てる必要があるローカル変数の数が完全に決定されます。スタック フレームは、ローカル変数テーブルのサイズ。

3. ローカル メソッド スタック

は基本的に仮想マシン スタックと似ていますが、異なる点は、仮想マシン スタックが仮想マシンによって実行される Java メソッドを提供することです。 、ローカル メソッド スタックはネイティブ メソッドを提供します。

4. ヒープ

Java ヒープとも呼ばれる GC ヒープは、Java 仮想マシンによって管理されるメモリの中で最大のメモリ領域であり、Java 仮想マシンによって共有されるメモリでもあります。各スレッド、JVM の起動時に作成されるリージョン。このメモリ領域には、オブジェクト インスタンスと配列 (すべて新しいオブジェクト) が格納されます。

サイズは、

-Xms

(最小値) および -Xmx (最大値) パラメータによって設定されます。 -Xms は、JVM の起動時に要求される最小メモリです。デフォルトは、オペレーティング システムの物理メモリの 1/64 ですが、1G 未満です。-Xmx は、JVM が適用できる最大メモリです。デフォルトは、物理メモリの 1/4 ですが、 1G 未満。デフォルトでは、空きヒープ メモリが 40% 未満の場合、JVM はヒープを -Xmx で指定されたサイズに増やします。この比率は -XX で指定できます。 MinHeapFreeRation=; 空きヒープ メモリが 70% を超えると、JVM はサイズを削減します。ヒープのサイズは、-Xms で指定されたサイズに達します。この比率は、XX:MaxHeapFreeRation= を通じて指定できます。 . 実行中のシステムでは、実行時にヒープのサイズが頻繁に調整されることを避けるために、通常は -Xms と -Xmx の値が同じに設定されます。 コレクターは世代別コレクション アルゴリズムを使用するようになったため、ヒープは新しい世代と古い世代に分割されます。新しい世代には主に、新しく作成されたオブジェクトとまだ古い世代に入っていないオブジェクトが格納されます。古い世代には、複数のマイナー GC を生き延びたオブジェクトが保存されます。

新しい世代: プログラムによって作成された新しいオブジェクトは、新しい世代からメモリを割り当てます。新しい世代は、
Eden Space

と 2 つの Survivor Space で構成されます。同じサイズ (通常は S0 と S1、または From と To とも呼ばれます)、新しい世代のサイズは、-Xmn パラメーター、Eden Space および -XX:SurvivorRation# を通じて指定できます。 ##Survivor Space のサイズも調整できます。 古い世代: キャッシュ オブジェクトなど、複数回の新しい世代の GC を生き延びたオブジェクトを保存するために使用されます。新しく作成されたオブジェクトが直接古い世代に入る場合もあります。主に 2 つの状況があります:

1. 大きなオブジェクトは、起動パラメータ -XX:PretenureSizeThreshold=1024 (単位はバイト、デフォルトは 0) によって設定でき、サイズを超えた場合にオブジェクトが割り当てられないことを表します。新しい世代ですが、新しい世代に直接配置されます。古い世代の割り当て。

2. 大きな配列オブジェクトの場合、配列内で参照される外部オブジェクトはありません。旧世代が占有するメモリサイズは、-Xmxに相当する値から-Xmnに相当する値を引いた値となります。

JVMの内部構造と動作仕組み

Young Generation        即图中的Eden + From Space + To Space
Eden                    存放新生的对象
Survivor Space          有两个,存放每次垃圾回收后存活的对象
Old Generation          Tenured Generation 即图中的Old Space 
                        主要存放应用程序中生命周期长的存活对象

5. プログラム カウンタ

は最小のメモリ領域です, その機能は、現在のスレッドによって実行されるバイトコードの行番号インジケーターです。仮想マシン モデルでは、バイトコード インタプリタは、作業中にこのカウンタの値を変更することによって、実行する必要がある次のバイトコードを選択します。命令などの基本的な機能、分岐、ループ、例外処理、スレッド回復はすべてカウンターに依存します。

3. 直接メモリ

直接メモリは仮想マシンのメモリの一部ではなく、Java 仮想マシンで定義されたメモリ領域でもありません。マシンの仕様。 jdk1.4 で新たに追加された NIO では、チャネルとバッファーの IO メソッドが導入されています。ネイティブ メソッドを呼び出してオフヒープ メモリを直接割り当てることができます。このオフヒープ メモリはローカル メモリであり、ヒープ メモリのサイズには影響しません。 。

4. Java ヒープ メモリの 10 の重要なポイント

  1. Java ヒープ メモリは、オペレーティング システムによって割り当てられます。システム JVM のメモリの一部。

  2. オブジェクトを作成すると、オブジェクトは Java ヒープ メモリに保存されます。

  3. ガベージ コレクションを容易にするために、Java ヒープ スペースは 3 つに分割されます。領域 。それぞれ、New Generation、Old Generation または Tenured Generation、および Perm Space と呼ばれます。

  4. JVM コマンド ライン オプション -Xms、-Xmx、-Xmn を使用して、Java ヒープ領域のサイズを調整できます。サイズの後に単位を示す「M」または「G」を忘れずに付けてください。たとえば、-Xmx256m を使用すると、最大ヒープ サイズを 256MB に設定できます。

  5. JConsole または Runtime.maxMemory()、Runtime.totalMemory()、Runtime.freeMemory() を使用して、Java のヒープ メモリのサイズを表示できます。

  6. コマンド "jmap" を使用してヒープ ダンプを取得し、"jhat" を使用してヒープ ダンプを分析できます。

  7. Java ヒープ スペースはスタック スペースとは異なり、コール スタックとローカル変数を格納するために使用されます。

  8. Java ガベージ コレクターは、デッド オブジェクト (使用されなくなったオブジェクト) によって占有されていたメモリを再利用し、Java ヒープ領域に解放するために使用されます。

  9. java.lang.outOfMemoryError が発生した場合でも、心配する必要はありません。ヒープ領域を増やすだけで十分な場合もありますが、頻繁に発生する場合は、ヒープ領域が存在するかどうかを確認する必要があります。 Java プログラムに問題があり、メモリ リークはありません。

  10. プロファイラーおよびヒープ ダンプ分析ツールを使用して、Java ヒープ領域を表示し、各オブジェクトに割り当てられているメモリ量を確認してください。

さらに関連する知識については、Java 基本チュートリアルコラム

を参照してください。

以上がJVMの内部構造と動作仕組みの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はoschina.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。