インタビューで尋ねなければならないJVMの知識-JVM機能の学習

ランタイムデータエリア

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

メモリパーティション

影付きの部分はすべてのスレッドで共有されるデータ領域であり、影なしの部分はスレッドで分離されたデータ領域です。

プログラムカウンター

プログラムカウンタレジスタは、現在のスレッドによって実行されているバイトコードの行番号インジケータと見なすことができる小さなメモリスペースです。バイトコードインタープリタは、動作時にこのカウンタの値を変更することによって選択されます。実行する必要のある次のバイトコード命令は、プログラム制御フローのインジケーターです。分岐、ループ、ジャンプ、例外処理、スレッド回復などの基本機能はすべて、このカウンターに依存して完了する必要があります。

どの時点でも、プロセッサは1つのスレッドでのみ命令を実行できます。スレッドの切り替え後に正しい位置に戻るには、各スレッドに独立したプログラムカウンターが必要であり、スレッド間のカウンターは相互に影響を与えません。したがって、プログラムカウンターのメモリスペースは各スレッド専用です。

注:スレッドがJavaメソッドを実行している場合、このカウンターは実行されている仮想マシンのバイトコード命令のアドレスを記録します。スレッドがネイティブメソッドを実行している場合、カウンター値は空である必要があります。 (未定義)。また、このメモリ領域はOutOfMemoryErrorには表示されません。

Java仮想マシンスタック

Java仮想マシンスタックはスレッド専用であり、そのライフサイクルはスレッドのライフサイクルと同じです。各メソッドが実行されると、Java仮想マシンは、ローカル変数テーブル、オペランドスタック、動的接続、メソッド出口などの情報を格納するスタックフレーム(スタックフレーム)を同期的に作成します各メソッドが呼び出されてから実行が完了するまでのプロセスは、仮想マシンスタックのプッシュからポップまでのスタックフレームのプロセスに対応します。

Java仮想マシンスタック

ローカル変数テーブルには、コンパイル中に認識できるさまざまなJava仮想マシンの基本的なデータタイプ(boolean、byte、char、short、int、float、long、double)とオブジェクト参照が格納されます。

ローカル変数テーブルに必要なメモリはコンパイル時に割り当てられ、ローカル変数テーブルのサイズはメソッドの実行中に変更されません。

スレッドによって要求されたスタックの深さが仮想マシンによって許可された深さよりも大きい場合、StackOverflowError例外がスローされます。Java仮想マシンのスタック容量を動的に拡張できる場合、スタックが拡張されて十分なメモリを適用できないときにOutOfMemoryError例外がスローされます。

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

ネイティブメソッドスタックは、仮想マシンで使用されるネイティブメソッドを提供します。その機能は、Java仮想マシンスタックに似ています。もちろん、ローカルメソッドスタックは、スタックの深さがオーバーフローした場合、またはスタックの拡張が失敗した場合に、それぞれStackOverflowErrorおよびOutOfMemoryError例外もスローします。

Javaヒープ

Javaヒープは、すべてのスレッドで共有されるメモリ領域であり、仮想マシンの起動時に作成されます。このメモリ領域の唯一の目的は、オブジェクトインスタンスを格納することであり、Javaワールドの「ほぼ」すべてのオブジェクトインスタンスがここにメモリを割り当てます。もちろん、テクノロジーが発展するにつれて、オブジェクトインスタンスは他の場所にも配布される可能性があります。

Javaヒープを細分化する目的は、メモリをより適切に再利用するか、メモリをより速く割り当てることです。

Javaヒープは、物理的に不連続なメモリスペースにある可能性がありますが、論理的には連続していると見なす必要があります。ただし、大きなオブジェクト(通常は配列オブジェクト)の場合、ほとんどの仮想マシンの実装では、単純さとストレージ効率のために、連続したメモリスペースが必要になる可能性があります。

インスタンスの割り当てを完了するためのメモリがJavaヒープになく、ヒープを拡張できなくなった場合、Java仮想マシンはOutOfMemoryError例外をスローします。

ヒープ

上の図は、Javaヒープの構造を示しています。

ヒープ内のオブジェクト割り当ての原則について:

オブジェクトは最初にエデンエリアに割り当てられます

大きな物は直接老後を迎えます

長寿命のオブジェクトは古い時代に入ります

メソッドエリア

メソッドエリアは、Javaヒープと同様に、各スレッドで共有されるメモリエリアであり、仮想マシンによってロードされたJITコンパイラによってコンパイルされたタイプ情報、定数、静的変数、コードキャッシュなどのデータを格納するために使用されます。

JDK 7のHotSpotは、元々永続生成に配置されていた文字列定数プールと静的変数を移動しましたが、JDK 8では、永続生成の概念は最終的に完全に廃止され、JRockitやJ9などのローカルメモリに実装されます。代わりにメタスペースが使用され、JDK 7の永続世代の残りのコンテンツ(主にタイプ情報)がメタスペースに移動されます。

上記の段落では、JDK8には永続的な生成はありませんが、メタスペースを使用していることに注意してください。JDK7では、多くの人がメソッド領域を永続的な世代と混同するのが好きでした。

ガベージコレクションの動作は、この領域では確かに比較的まれですが、データが永続的な世代の名前として「永続的」としてメソッド領域に入力されるわけではありません。この領域のメモリ回復の目標は、主に定数プールの回復と型のアンロードです。メソッド領域が新しいメモリ割り当て要件を満たすことができない場合、OutOfMemoryError例外がスローされます。

ランタイム定数プール

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

ランタイム定数プールはメソッド領域の一部です。定数プールがメモリに適用できなくなると、OutOfMemoryErrorがスローされます。

ダイレクトメモリ

ダイレクトメモリ(ダイレクトメモリ)は、実行中の仮想マシンのデータ領域の一部ではありませんが、メモリのこの部分も頻繁に使用され、OutOfMemoryErrorを引き起こす可能性があります。

オブジェクト

HotSpot仮想マシンでは、ヒープメモリ内のオブジェクトのストレージレイアウトは、オブジェクトヘッダー(ヘッダー)、インスタンスデータ(インスタンスデータ)、および配置パディング(パディング)の3つの部分に分割できます。

HotSpot仮想マシンオブジェクトのオブジェクトヘッダー部分には、2種類の情報が含まれています。最初のタイプは、オブジェクト自体のランタイムデータを格納するために使用され、「マークワード」とも呼ばれます。「マークワード」の情報は次のとおりです。

マークワード

Javaプログラムは、スタック上の参照データを介してヒープ上の特定のオブジェクトを操作します。主流のアクセス方法は、主にハンドルとダイレクトポインタを使用します。

  • ハンドルアクセス:メモリの一部は、ハンドルプールとしてJavaヒープに分割できます。オブジェクトのハンドルアドレスは参照に格納され、ハンドルにはオブジェクトインスタンスデータとタイプデータの特定のアドレス情報が含まれます。

  • 直接ポインタアクセス:Javaヒープ内のオブジェクトのメモリレイアウトでは、アクセスタイプデータに関連する情報を配置する方法を考慮する必要があります。オブジェクトに格納される参照は、オブジェクトのアドレスです。オブジェクト自体にのみアクセスする場合は、追加の間接アクセスオーバーヘッドは必要ありません。

通常、HotSpot仮想マシンは2番目の直接ポインターアクセスを使用します。

ダイレクトポインタ

ここで私は質問を提起します、誰もが考えることができます:

ヒープオーバーフロー例外とスタックオーバーフロー例外のコードを作成するにはどうすればよいですか?

これはインタビューでよくある質問です。ヒープオーバーフローの例外については、オブジェクトの作成とオブジェクトのヒープメモリのバーストを考えることができます。スタックオーバーフローの例外については、スタックフレームをスタックに埋める方法を考えることができます。

過去に推奨

QRコードをスキャンして、よりエキサイティングになります。または、WeChatLvshen_9を検索すると、返信してバックグラウンドで情報を取得できます

1.回复"java" 获取java电子书;

2.回复"python"获取python电子书;

3.回复"算法"获取算法电子书;

4.回复"大数据"获取大数据电子书;

5.回复"spring"获取SpringBoot的学习视频。

6.回复"面试"获取一线大厂面试资料

7.回复"进阶之路"获取Java进阶之路的思维导图

8.回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)

9.回复"总结"获取Java后端面试经验总结PDF版

10.回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)

11.回复"并发导图"获取Java并发编程思维导图(xmind终极版)

もう1つ:[マイベネフィット]をクリックして、さらに驚きを持ってください。

おすすめ

転載: blog.csdn.net/wujialv/article/details/109173690