序文
Javaメモリ領域は、主にプログラムカウンター、Java仮想マシンスタック、ローカルメソッドスタック、Javaヒープ、メソッドエリア、ランタイム定数プールで構成されています。この記事では、Javaメモリ領域の分割と例外について詳細に紹介します。以下ではあまり言いません。詳細な紹介を一緒に見てみましょう。
ランタイムデータエリア
JVMがJavaプログラムを実行すると、メモリをいくつかの異なるデータ領域に分割します。
プログラムカウンター
プライベートスレッド。現在のスレッドによって実行されるバイトコードの行番号インジケーターと見なすことができます。 ByteCodeインタープリターの作業は、このカウント値を変更することにより実行される次のbytecode命令を読み取ることです。
マルチスレッドは、スレッドを順番に切り替え、プロセッサの実行時間を割り当てることにより実現されます。いつでも、カーネルは1つのスレッドで命令のみを実行できます。スレッドスイッチング後に正しい実行位置に復元するには、各スレッドに独立したプログラムカウンターが必要です。これは、「スレッドプライベート」の冒頭で言及したことです。スレッドが実行している方法がJavaメソッドである場合、カウンターは仮想マシンバイトコードの命令アドレスを記録します。ネイティブ方法の場合、カウンター値は空です。プログラムカウンターは、Java仮想マシン仕様でOOM(OutOfMemoryError)の状況が指定されていない唯一の領域です。
Java仮想マシンスタック
スレッドはプライベートで、スレッドと同じライフサイクルがあります。 Java Virtual Machineスタックは、Javaメソッドのメモリモデルを説明します。各メソッドは、実行時にスタックフレームを作成し、ローカル変数テーブル、オペランドスタック、動的リンク、およびメソッドエグジット情報を保存します。呼び出しから最後まで、各メソッドは、仮想マシンスタック内のこのスタックフレームのスタックエントリと終了プロセスに対応します。ローカル変数テーブルは、さまざまな基本データ型(int、double、char、byteなど)、オブジェクト参照(オブジェクト自体ではなく)、およびreturnAddressタイプ(バイトコードアドレスを指す)を保存します。
この分野での2つの可能な例外:
ローカルメソッドスタック
上記の仮想マシンスタックは、JVMのJavaメソッドサービスを実行し、ローカルメソッドはネイティブサービスを実行します。その他は仮想マシンスタックに似ており、StackoverFlowerrorとOutofMemoryErrorもスローされます。
Java Heap
一般に「スタックメモリ」と「ヒープメモリ」と呼ばれるものと呼ばれ、前者は仮想マシンスタックを指し、後者はJavaヒープを指します。 Javaヒープはスレッドで共有されています。仮想マシンが開始されたときに作成されます。
Javaヒープの役割は、オブジェクトインスタンスを保存することです。 Javaヒープは、物理的に不連続なメモリスペースにある可能性があり、論理的に連続的にのみ必要です。
メソッド領域
スレッドで共有されるエリア。クラス情報、定数、静的変数、コンパイラによってコンパイルされたコードなどのデータは、仮想マシンによってロードされています。メソッド領域がメモリの割り当て要件を満たすことができない場合、OutOfMemoryErrorがスローされます。
ランタイム定数プール
ランタイム定数プールはメソッド領域の一部です。 Cは、コンピレーション期間中に生成されたさまざまなリテラル定数とシンボリック参照を保存するために使用され、クラスロード後にメソッドエリアに入るランタイム定数プールに保存されます。 Java言語では、コンピレーション期間中にのみ定数を生成する必要はありません。言い換えれば、実行期間中に新しい定数を配置できます。
直接メモリ
直接メモリは、仮想マシンランタイムデータ領域の一部ではなく、メモリ領域でもありません。ネイティブマシンの直接メモリの割り当ては、Javaヒープのサイズによって制限されませんが、結局メモリです。各メモリ領域の合計が物理メモリの制限よりも大きい場合、OutOfMemoryErrorは引き続き表示されます。
オブジェクト作成プロセス
仮想マシンは「新しい」命令に遭遇します:
オブジェクトのメモリレイアウト
メモリに保存されているオブジェクトのレイアウトは、3つの領域に分割できます。
オブジェクトヘッダー:ハッシュコード、GC生成年齢、ロックステータスフラグ、スレッドで保持されているロック、バイアススレッドIDなどのオブジェクト独自のランタイムデータを保存します。別の部分は、オブジェクトのクラスメタデータへのポインターです。仮想マシンは、このポインターを使用して、オブジェクトが属するクラスインスタンスを決定します。
インスタンスデータ:オブジェクトの真に有効な情報、プログラムで定義されているさまざまなタイプのフィールドのコンテンツ。
アライメントサプリメント:非必須、居住者の役割。
オブジェクトアクセスポジショニング
Javaプログラムは、スタックの参照を介してヒープ上のインスタンスオブジェクトを操作します。例えば
人p = new person();
ここでPは参照であり、新しいによって生成された人物はインスタンスです。
このリファレンスでは、ヒープ内のオブジェクトの特定の場所を見つけてアクセスする方法を指定しません。 2つの主流アクセス方法があります。
ハンドル。メモリの一部は、オブジェクトのハンドルアドレスを参照するハンドルプールとしてJavaヒープに分割され、ハンドルにはオブジェクトインスタンスデータとタイプデータが含まれます。利点は、オブジェクトが移動されたときに、ハンドル内のアドレスを変更するだけで、参照自体を変更する必要がないことです。
直接ポインター。オブジェクトアドレスは参照に直接保存されます。利点は、速度が高速であり、参照がインスタンスオブジェクトのアドレスを直接表すため、ポインター位置操作が保存されることです。これはまさにSun Hotspotの使用方法です。
要約します
上記は、この記事のコンテンツ全体です。この記事の内容には、すべての人の研究や仕事に特定の参照値があることを願っています。ご質問がある場合は、メッセージを残してコミュニケーションをとることができます。 wulin.comへのご支援ありがとうございます。