JVMシリーズの詳細1:JVMメモリ構造(ランタイムデータ領域)
2971 ワード
微信公衆番号:Java週刊誌は注目を歓迎し、一緒に勉強し、一緒に進歩します!最近の更新:
Java仮想マシンのマルチスレッドは、スレッドがプロセッサの実行時間を順番に切り替えて割り当てることによって実現されるため、いずれの決定された時点でも、1つのプロセッサは1つのスレッドの命令しか実行しません.したがって,スレッド切替後に正しい位置に復元するためには,各スレッドに独立したプログラムカウンタが必要であり,各スレッド間のカウンタは互いに影響を及ぼさず,独立して記憶されているので,このようなメモリを「スレッドプライベート」と呼ぶ.
スレッドがJavaメソッドを実行している場合、このカウンタは実行中の仮想マシンバイトコード命令のアドレスを記録する.Nativeメソッドが実行されている場合、このカウンタの値は空です.この領域は、Java仮想マシン仕様でOutOfMemoryErrorの状況が規定されていない唯一の領域です.
2.仮想マシンスタック(VM Stack)仮想マシンスタックはスレッドプライベートであり、そのライフサイクルはスレッドと同じである.仮想マシンスタックはJavaメソッドが実行するメモリモデルを記述する.各メソッドは、実行と同時に、ローカル変数テーブル、オペランドスタック、ダイナミックリンク、メソッド出口などの情報を格納するスタックニードルを作成します.各メソッドは、呼び出しから実行が完了するまでのプロセスに対応し、1つのスタックフレームが仮想マシンにスタックを出てスタックに入るプロセスに対応する.
ローカル変数テーブルには何が保管されていますか?1.コンパイル期間で分かる8種類の基本データ型.2.オブジェクト参照(referenceタイプ、オブジェクトの開始アドレスを指す参照ポインタ、またはオブジェクトを表すハンドルまたは他のオブジェクトに関連する位置を指す)3.returnAddressタイプ(バイトコード命令のアドレスを指す)
64ビット長のlongとdoubleタイプのデータは2つのローカル変数空間を占有し、残りのデータ型は1つしか占有しません.ローカル変数テーブルに必要なメモリ領域はコンパイル中に割り当てが完了し、メソッドに入ると、このメソッドはフレームにどのくらいのローカル変数空間を割り当てる必要があるかを完全に決定し、メソッドの実行中にローカル変数テーブルのサイズを変更しません.
Java仮想マシン仕様では、スレッド要求のスタックの深さが仮想マシンが許容する深さより大きい場合、StackOverflowError異常が投げ出されるという2つの異常状況がこの領域に規定されています.仮想マシンスタックが動的に拡張できる場合、拡張時に十分なメモリを申請できない場合、OutOfMemoryError異常が放出されます.
3.ローカルメソッドスタック(Native Method Stack)ローカルメソッドスタックと仮想マシンスタックが果たす役割は非常に類似しており、それらの違いは、仮想マシンがJavaメソッド(すなわちバイトコード)サービスを実行するために仮想マシンが実行する仮想マシンが使用するnativeメソッドサービスにすぎない.
4.ヒープ(Heap)ほとんどのアプリケーションでは、JavaヒープはJava仮想マシンが管理するメモリの中で最大のブロックです.Javaスタックは、すべてのスレッドで共有されるメモリ領域であり、仮想マシンの起動時に作成されます.このメモリ領域の唯一の目的は、メモリインスタンスを格納することです.ほとんどのオブジェクトインスタンスがここでメモリを割り当てます.この点、Java仮想マシン仕様では、すべてのオブジェクトインスタンスおよび配列がスタックに割り当てられることを説明します.しかし、JITコンパイラの発展と脱出分析技術が成熟するにつれて、スタック上の割り当て、スカラーの置き換え-最適化技術はいくつかの微妙な変化を招き、すべてのオブジェクトがスタック上に割り当てられるのはそれほど「絶対」ではありません.
Javaヒープはゴミ収集器管理の主なエリアであるため、「GC」ヒープとも呼ばれることが多い.メモリ割り当ての観点から、スレッド共有Javaスタックには、複数のスレッドのプライベートな割り当てキャッシュ領域(Thread Local Allocation Buffer,TLAB)が分割される可能性がある.ただし、どの領域においても、格納されているのはオブジェクトインスタンスであり、メモリをよりよく回収したり、メモリの割り当てをより速くしたりすることを目的としています.
ヒープメモリ拡張パラメータ:-Xmxおよび-Xms
5.メソッド領域メソッド領域は、スタックと同様に、仮想マシンにロードされたクラス情報、定数、静的変数、インスタントコンパイラによってコンパイルされたコードなどのデータを格納するためのスレッド共有メモリ領域である.Java仮想マシン仕様では、メソッド領域はスタックの論理部分として記述されていますが、Javaスタックと区別するためにNon-Heap(非スタック)という名前があります.
6.ランタイムプール(Runtime Constant Pool)ランタイムプールはメソッド領域の一部です.Classファイルには、クラスのバージョン、フィールド、メソッド、インタフェースなどの記述情報のほかに、コンパイル中に生成された様々な字面量と記号参照を格納する定数プールがあります.この部分は、クラスがロードされた後にメソッド領域に入るランタイム定数プールに格納されます.
7.ダイレクトメモリ(DirectMemory)ダイレクトメモリは、仮想マシンの実行時データ領域の一部ではなく、Java仮想マシン仕様で定義されているメモリ領域でもありません.しかし、この部分のメモリも頻繁に使用され、OutOfMemoryError異常を引き起こす可能性があります.
jdk 1.4にNIOクラスが新たに追加され、Native関数ライブラリを使用してスタック外メモリを直接割り当て、Javaスタックに格納されたDirectByteBufferオブジェクトをメモリの導入として動作させるチャネルベースとキャッシュ領域ベースのIO方式が導入された.これにより、いくつかのシーンでパフォーマンスが大幅に向上します.
2018-04-14
1.プログラムカウンタプログラムカウンタ(Program Counter Register)は、現在のスレッドで実行されているバイトコードの行番号器と見なすことができる小さなメモリ領域である.仮想マシンコンセプトモデルでは、バイトコード解釈器が動作する場合、このカウンタの値を変更することで、次の実行するバイトコード命令、ブランチ、ループ、ジャンプ、異常処理、スレッドリカバリなどの基礎機能を選択するには、このカウンタに依存して完了する必要があります.Java仮想マシンのマルチスレッドは、スレッドがプロセッサの実行時間を順番に切り替えて割り当てることによって実現されるため、いずれの決定された時点でも、1つのプロセッサは1つのスレッドの命令しか実行しません.したがって,スレッド切替後に正しい位置に復元するためには,各スレッドに独立したプログラムカウンタが必要であり,各スレッド間のカウンタは互いに影響を及ぼさず,独立して記憶されているので,このようなメモリを「スレッドプライベート」と呼ぶ.
スレッドがJavaメソッドを実行している場合、このカウンタは実行中の仮想マシンバイトコード命令のアドレスを記録する.Nativeメソッドが実行されている場合、このカウンタの値は空です.この領域は、Java仮想マシン仕様でOutOfMemoryErrorの状況が規定されていない唯一の領域です.
2.仮想マシンスタック(VM Stack)仮想マシンスタックはスレッドプライベートであり、そのライフサイクルはスレッドと同じである.仮想マシンスタックはJavaメソッドが実行するメモリモデルを記述する.各メソッドは、実行と同時に、ローカル変数テーブル、オペランドスタック、ダイナミックリンク、メソッド出口などの情報を格納するスタックニードルを作成します.各メソッドは、呼び出しから実行が完了するまでのプロセスに対応し、1つのスタックフレームが仮想マシンにスタックを出てスタックに入るプロセスに対応する.
ローカル変数テーブルには何が保管されていますか?1.コンパイル期間で分かる8種類の基本データ型.2.オブジェクト参照(referenceタイプ、オブジェクトの開始アドレスを指す参照ポインタ、またはオブジェクトを表すハンドルまたは他のオブジェクトに関連する位置を指す)3.returnAddressタイプ(バイトコード命令のアドレスを指す)
64ビット長のlongとdoubleタイプのデータは2つのローカル変数空間を占有し、残りのデータ型は1つしか占有しません.ローカル変数テーブルに必要なメモリ領域はコンパイル中に割り当てが完了し、メソッドに入ると、このメソッドはフレームにどのくらいのローカル変数空間を割り当てる必要があるかを完全に決定し、メソッドの実行中にローカル変数テーブルのサイズを変更しません.
Java仮想マシン仕様では、スレッド要求のスタックの深さが仮想マシンが許容する深さより大きい場合、StackOverflowError異常が投げ出されるという2つの異常状況がこの領域に規定されています.仮想マシンスタックが動的に拡張できる場合、拡張時に十分なメモリを申請できない場合、OutOfMemoryError異常が放出されます.
3.ローカルメソッドスタック(Native Method Stack)ローカルメソッドスタックと仮想マシンスタックが果たす役割は非常に類似しており、それらの違いは、仮想マシンがJavaメソッド(すなわちバイトコード)サービスを実行するために仮想マシンが実行する仮想マシンが使用するnativeメソッドサービスにすぎない.
4.ヒープ(Heap)ほとんどのアプリケーションでは、JavaヒープはJava仮想マシンが管理するメモリの中で最大のブロックです.Javaスタックは、すべてのスレッドで共有されるメモリ領域であり、仮想マシンの起動時に作成されます.このメモリ領域の唯一の目的は、メモリインスタンスを格納することです.ほとんどのオブジェクトインスタンスがここでメモリを割り当てます.この点、Java仮想マシン仕様では、すべてのオブジェクトインスタンスおよび配列がスタックに割り当てられることを説明します.しかし、JITコンパイラの発展と脱出分析技術が成熟するにつれて、スタック上の割り当て、スカラーの置き換え-最適化技術はいくつかの微妙な変化を招き、すべてのオブジェクトがスタック上に割り当てられるのはそれほど「絶対」ではありません.
Javaヒープはゴミ収集器管理の主なエリアであるため、「GC」ヒープとも呼ばれることが多い.メモリ割り当ての観点から、スレッド共有Javaスタックには、複数のスレッドのプライベートな割り当てキャッシュ領域(Thread Local Allocation Buffer,TLAB)が分割される可能性がある.ただし、どの領域においても、格納されているのはオブジェクトインスタンスであり、メモリをよりよく回収したり、メモリの割り当てをより速くしたりすることを目的としています.
ヒープメモリ拡張パラメータ:-Xmxおよび-Xms
5.メソッド領域メソッド領域は、スタックと同様に、仮想マシンにロードされたクラス情報、定数、静的変数、インスタントコンパイラによってコンパイルされたコードなどのデータを格納するためのスレッド共有メモリ領域である.Java仮想マシン仕様では、メソッド領域はスタックの論理部分として記述されていますが、Javaスタックと区別するためにNon-Heap(非スタック)という名前があります.
6.ランタイムプール(Runtime Constant Pool)ランタイムプールはメソッド領域の一部です.Classファイルには、クラスのバージョン、フィールド、メソッド、インタフェースなどの記述情報のほかに、コンパイル中に生成された様々な字面量と記号参照を格納する定数プールがあります.この部分は、クラスがロードされた後にメソッド領域に入るランタイム定数プールに格納されます.
7.ダイレクトメモリ(DirectMemory)ダイレクトメモリは、仮想マシンの実行時データ領域の一部ではなく、Java仮想マシン仕様で定義されているメモリ領域でもありません.しかし、この部分のメモリも頻繁に使用され、OutOfMemoryError異常を引き起こす可能性があります.
jdk 1.4にNIOクラスが新たに追加され、Native関数ライブラリを使用してスタック外メモリを直接割り当て、Javaスタックに格納されたDirectByteBufferオブジェクトをメモリの導入として動作させるチャネルベースとキャッシュ領域ベースのIO方式が導入された.これにより、いくつかのシーンでパフォーマンスが大幅に向上します.