Javaパフォーマンスのランタイムデータ領域(ターン)

1.ランタイムデータ領域

Javaプログラムの実行中に、Java仮想マシンは管理するメモリをいくつかの異なるデータ領域に分割します。これらの領域には、独自の目的と作成および破棄の時間があります。一部の領域は仮想マシンプロセスの開始時に存在し、一部の領域はユーザースレッドの開始と終了に応じて作成および破棄されます。

 

 

 

 

 

 

1)プログラムカウンタ

プログラムカウンタレジスタは、現在のスレッドによって実行されるバイトコードの行番号のインジケータと見なすことができる小さなメモリスペースです。仮想マシンの概念モデル(概念モデルのみ、さまざまな仮想マシンをより効率的な方法で実装できます)では、バイトコードインタープリターは、このカウンターの値を変更して、次に実行するカウンターを選択することで機能します。バイトコード命令、分岐、ループ、ジャンプ、例外処理、およびスレッドリカバリはすべて、完了するためにこのカウンタに依存する必要があります。

 

Java仮想マシンのマルチスレッド化は、スレッドの切り替えとプロセッサの実行時間の割り当てによって実現されるため、いずれかが決定されると、プロセッサ(マルチコアプロセッサの場合はコア)は1つの命令のみを実行します。スレッドで。したがって、スレッドの切り替え後に正しい位置に復元するには、各スレッドに独立したプログラムカウンタが必要です。スレッド間のカウンタは相互に影響を与えず、独立して格納されます。このタイプのメモリ領域を「スレッドプライベート」メモリと呼びます。

 

スレッドがJavaメソッドを実行している場合、このカウンターは実行されている仮想マシンのバイトコード命令のアドレスを記録します。スレッドがネイティブメソッドを実行している場合、カウンター値は空(未定義)です。このメモリ領域は、Java仮想マシン仕様でOutOfMemoryErrorがない唯一の領域です。

 

 

2)Java仮想マシンスタック

 

 

 

 

プログラムカウンタと同様に、Java仮想マシンスタックもスレッドプライベートであり、そのライフサイクルはスレッドのライフサイクルと同じです。仮想マシンスタックは、Javaメソッド実行のメモリモデルを記述します。各Javaメソッドが実行されると、ローカル変数テーブル、オペランドスタック、動的リンク、メソッド出口などの情報を格納するスタックフレームが作成されます。呼び出しから実行の完了までの各メソッドのプロセスは、仮想マシンスタック内のこのスタックフレームをプッシュしてスタックからポップアウトするプロセスに対応します。

 

私たちが話しているスタックは、私たちが話している仮想マシンスタック、または仮想マシンスタックのローカル変数テーブル部分です。ローカル変数テーブルには、コンパイラーが認識しているさまざまな基本データ型(boolean、byte、char、short、int、float、long、double)、オブジェクト参照(参照型、オブジェクト自体と同等ではない、オブジェクトへのポインタ開始アドレスの参照ポインタは、オブジェクトまたはこのオブジェクトに関連する他の場所を表すハンドルでもかまいません)およびreturnAddressタイプ(バイトコード命令のアドレスを指す)。

 

64ビットのlongデータとdoubleデータは2つのローカル変数スペース(スロット)を占有し、残りのデータ型は1つのみを占有します。ローカル変数テーブルに必要なメモリスペースはコンパイル時に割り当てられます。メソッドを入力すると、このメソッドに必要なフレームに割り当てられるローカル変数スペースの量が完全に決定され、ローカル変数テーブルのサイズは変更されません。メソッドの実行。

 

Java仮想マシンの仕様では、この領域に2つの例外が指定されています。スレッドによって要求されたスタックの深さが仮想マシンによって許可された深さよりも大きい場合、StackOverflowError例外がスローされます。仮想マシンのスタックを動的に拡張できる場合、拡張機能を適用できない場合十分なメモリに達すると、OutMemoryErrorがスローされます。

 

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

ネイティブメソッドスタックと仮想マシンスタックが果たす役割は非常に似ています。両者の違いは、仮想マシンスタックが仮想マシンにJavaメソッド(つまりバイトコード)を実行するのに対し、ネイティブメソッドスタックは仮想マシンで使用されるネイティブメソッド。仮想マシンスタックと同様に、ローカルメソッドスタック領域もStackOverflowErrorとOutOfMemoryErrorをスローします。

 

4)Javaヒープ

Javaヒープは、Java仮想マシンによって管理される最大のメモリです。Javaヒープは、すべてのスレッドで共有されるメモリ領域であり、仮想マシンの起動時に作成されます。このメモリ領域の唯一の目的はオブジェクトインスタンスを格納することであり、ほとんどすべてのオブジェクトインスタンスがここにメモリを割り当てます。Javaヒープは、ガベージコレクターによって管理される主要な領域であり、「GCヒープ(ガベージコレクションヒープ)」と呼ばれることがよくあります。  

 

メモリ回復の観点から、コレクターは基本的に世代別収集アルゴリズムを使用するようになったため、Javaヒープは、新世代と旧世代に細分することもできます。より詳細なものには、Edenスペース、From Survivorスペース、ToSurvivorスペースがあります。

 

メモリ割り当ての観点から、スレッドによって共有されるJavaヒープは、複数のスレッドプライベート割り当てバッファに分割できますが、分割がどのようなものであっても、ストレージの内容とは関係ありません。ストレージは、どの領域に関係なく、それでもオブジェクトインスタンスです。さらに分割の目的は、メモリをより適切に再利用するか、メモリをより速く割り当てることです。

 

Java仮想マシンの仕様によれば、Javaヒープは、ディスクスペースと同様に論理的に連続している限り、物理的に不連続なメモリスペースに配置できます。実装すると、固定サイズとして実装できます。拡張することもできますが、現在の主流の仮想マシンはスケーラビリティに従って実装されます(-XmxおよびXmsによって制御されます)。インスタンスの割り当てを完了するためのメモリがヒープになく、ヒープを拡張できなくなった場合は、 OutofMemoryError例外をスローします。

 

 

5)メソッドエリア

 

メソッド領域は、Javaヒープと同様に、各スレッドによって共有されるメモリ領域であり、クラス情報、定数、静的変数、ジャストインタイムコンパイラによってコンパイルされたコードなどのデータを格納するために使用されます。仮想マシン。Java仮想マシン仕様では、メソッド領域はヒープの論理部分として記述されていますが、Javaヒープと区別するために非ヒープ(非ヒープ)と呼ばれるエイリアスがあります。

 

HotSpot仮想マシンでのプログラムの開発と展開に慣れている開発者にとって、多くの人はこのメソッドを「永続的な生成」(永続的なFeneration)と呼ぶことを好みます。本質的に、HotSpot仮想マシンのために2つは同等ではありません。設計チームは、GC世代コレクションをメソッド領域に拡張するか、永続世代を使用してメソッド領域を実装することを選択しました。これにより、HotSpotのガベージコレクターがメモリのこの部分をJavaヒープのように管理できるため、具体的に書き込む必要がなくなります。メソッド領域の場合メモリ管理コードの作業。他の仮想マシンの場合、永続的な生成の概念はありません。

 

原則として、メソッド領域の実装方法は仮想マシンの実装詳細に属し、仮想マシンの仕様による制限はありませんが、永続生成を使用してメソッド領域を実装することはお勧めできません。メモリオーバーフローの問題が発生しやすくなります(永続的な生成には--XX:MaxPermSiza)制限があります。

 

Java仮想マシンの仕様では、メソッド領域が非常に簡単に制限されます。Javaヒープのように連続したメモリを必要とせず、固定サイズまたは拡張可能を選択できることに加えて、ガベージコレクションを実装しないことも選択できます。比較的言えば、この領域ではガベージコレクションの動作は比較的まれです。ただし、データが永続世代の名前として「永続的」としてメソッド領域に入力されるわけではありません。この領域でのメモリ回復の目標は、主に定数プールの回復と型のアンロードです。一般的に、この領域の回復パフォーマンス、特に型のアンロードは、満たすのがより困難です。条件は非常に厳しいです。しかし、地域のこの部分の回復が必要です。

 

仮想マシン仕様の規定によると、メソッドがメモリ割り当て要件を満たせない場合、OutOfMemoryError例外がスローされます。

 

6)ランタイム定数プール

 

ランタイム定数プールはメソッド領域の一部です。クラスファイル内のクラスバージョン、フィールド、メソッド、およびインターフェイスの説明情報に加えて、コンパイラによって生成されたさまざまなリテラルおよびシンボリック参照を格納するために使用される定数プール(定数プールテーブル)もあります。コンテンツの一部クラスがロードされた後、メソッド領域のランタイム定数プールに格納されます。

 

Java仮想マシンには、クラスファイルの各部分(当然、定数プールを含む)の形式に関する厳しい規制があります。各バイトの格納に使用されるデータの種類は、認識、ロード、および指定する前に、仕様の要件を満たす必要があります。仮想マシンによって実行されます。ただし、ランタイム定数の場合、Java仮想マシンの仕様では詳細な要件はありません。さまざまなプロバイダーによって実装された仮想マシンは、独自のニーズに応じてこのメモリ領域を実装できます。ただし、一般的には、クラスファイルに記述されているシンボリック参照を保存することに加えて、変換された直接参照もランタイム定数プールに保存されます。

 

7)ダイレクトメモリ

ダイレクトメモリは、仮想マシンランタイムのデータ領域の一部ではなく、Java仮想マシン仕様で定義されているメモリ領域でもありません。ただし、メモリのこの部分も頻繁に使用されるため、OutOfMemoryErrorが表示される場合があります。

おすすめ

転載: blog.csdn.net/ccpit2b2c/article/details/109327078