あなたは本当に JVM を理解していますか? JVM のメモリ領域とその機能は何ですか?

あなたは本当に JVM を理解していますか? JVM のメモリ領域とその機能は何ですか?

1.0 序文

前回は、.class ファイルが jvm にロードされる方法について説明しました。しかし、JVM ではメモリはどのように分割されるのでしょうか?このメモリはどのメモリにロードされますか? JVM のメモリ分割も、面接中に必ず尋ねられる質問です。

1.1 JVM メモリ領域の分割とは何ですか?

実際、この問題は非常に単純です。 JVM が私たちが書いたコードを実行するとき、複数のメモリ空間を使用する必要があります。異なるメモリ空間は異なるデータを保存するために使用され、システムを実行するために記述したコード フローと連携します。

最も簡単な例を見てみましょう。これで、JVM が後続の操作のためにクラスをメモリにロードすることがわかりました。そこでお聞きしたいのですが、これらのクラスはメモリにロードされた後、どこに配置されるのでしょうか?この質問について考えたことはありますか?

したがって、作成したクラスを保存するためのメモリ領域が JVM 内に存在する必要があります。

定義したメンバー変数、クラス変数、メソッド、ローカル変数などはすべて、JVM メモリ内のメモリの一部に対応し、記録および保存されます。

2.0 ストレージクラスメソッド領域

JDK 1.8 より前のバージョンでは、JVM の領域を表します。バージョン 1.8 以降、この領域の名前は「Matespace」に変更されました。これは「メタデータ スペース」と考えることができます。もちろん、主に自分たちで書いた各種クラスの関連情報が格納されます。

例えば。以下の2つのクラスがあります。 People クラスにはメンバー変数はありませんが、Student クラスには name というクラス変数があります。

  1. パブリッククラスStudent{
  2. プライベート静的文字列= "lisi" ;
  3. }
  4. パブリッククラス People {
  5. 公共 静的void main(){
  6. 学生 学生 = 新しい学生();
  7. }
  8. }

これら 2 つのクラスが JVM にロードされると、このメソッド領域に格納されます (注: 以前の章を読んでいれば、ここでのロードとは、ロード -> 検証 -> 準備 -> 解析 -> 初期化を意味し、クラスのすべてのクラス変数に値が割り当てられることを理解できます)。下記の通り

3.0 プログラムコード命令を実行するためのカウンタ

作成した .java ファイルがコンパイルされた後、jvm にロードされるクラス オブジェクトは .class ファイルであることがわかっています。

コンパイル後、コードはコンピュータが理解できるバイトコードにコンパイルされます。この .calss ファイルは、コードからコンパイルされたバイトコードです。

メモリにロードされると、バイトコード実行エンジンが動作を開始します。コンパイルしたコード命令を実行するには、以下に示すように

ここで疑問になるのは、バイトコード実行エンジンが現在実行しているコード行を記録するためにメモリ領域が必要かどうかです。この特別なメモリ領域は「プログラムカウンタ」です。

このプログラム カウンターは、現在実行されているバイトコード命令の場所を記録するために使用されます。

以下のように表示されます。

この時点で、混乱する人もいると思います。現在のコードシーケンスに従って実行するだけです。実行場所を記録する必要があるのはなぜですか?

記述するコードによって複数のスレッドが開始され、異なるコードが同時に実行される可能性があるためです。現在のスレッドがこのコードの実行をまだ完了しておらず、コンテキストが別のコードに切り替えられている可能性があります。

スレッドが再び前のコードにコンテキストを切り替える場合、現在のスレッドがどのバイトコードを実行したかを記録するための特別なレコードが必要になります。したがって、各スレッドには独自のプログラム カウンターがあります。

以下のように表示されます。

4.0 Java仮想マシンスタック

Java コードが実行されると、スレッドはメソッド内のコードを実行する必要があります。

スレッドがメソッドを実行するとき、そのメソッドにローカル変数がある場合は、ローカル変数のデータ情報を格納するための領域が必要になります。この領域は Java 仮想マシン スタックと呼ばれます。

各スレッドには独自の Java 仮想マシン スタックがあります。たとえば、メイン メソッドが実行されると、メイン メソッドで定義されたローカル変数を格納するメイン スレッドが存在します。

  1. 公共 静的void main(){
  2. People people = new People();
  3. 整数i = 9;
  4. }

たとえば、上記の main() メソッドには、実際には「people」というローカル変数があり、これは People のインスタンス オブジェクトを参照します。今のところこのオブジェクトは無視します。次に、「i」と呼ばれるローカル変数があります。

以下のように表示されます。


スタックのデータ構造、つまり後入れ先出しを誰もが知っておくべきだと思います。メソッドが実行されると、スタック フレームがポップされ、その中のローカル変数情報がメモリから削除されます。したがって、ローカル変数はスレッドセーフです。現在のスレッドだけがこの値を取得できるためです。

なぜ後入先出データ構造を使用するのですか?

メソッド a がメソッド b を同期的に呼び出すとします。この場合、メソッド a のスタック フレームが最初にスタックにプッシュされ、次にメソッド b のスタック フレームがスタックにプッシュされます。メソッド b が実行されると、メソッド b のスタック フレームがポップされ、メソッド a の実行が続行されます。したがって、後入れ先出しのスタック構造を使用するのが最適です。

現時点での JVM のメモリ モデル図は次のとおりです。


5.0 Java仮想マシンのヒープメモリ

この思い出はとても大切なものです。

インスタンス化するすべてのオブジェクトはこのメモリに保存されます。このインスタンス化されたオブジェクトには、いくつかのデータが含まれます。上記のコードを例として使用します。

  1. パブリッククラスStudent{
  2. プライベート文字列= "lisi" ;
  3. パブリック文字列getName(){
  4. 戻る 名前;
  5. }
  6. }
  7. パブリッククラス People {
  8. 公共 静的void main(){
  9. 学生 学生 = 新しい学生();
  10. 学生の名前を取得します。
  11. }
  12. }

このコードを引き続き使用すると、メイン スレッドが main() メソッドを実行すると、最初にヒープ メモリ内で Student オブジェクトがインスタンス化され、次にローカル変数に student が作成されます。 Student は、インスタンス化された Student オブジェクトのメモリ アドレスを格納します。次に、Student オブジェクトの getName() メソッドを実行します。

以下のように表示されます。

上の図からわかるように、スタック スペースは閉じられており、スレッド セーフですが、すべてのスレッドが実際にヒープ メモリ スペースを共有できるため、スレッドのセキュリティが主に発生するのはヒープ メモリです。

現時点での、jvm のメモリ分割の最終モデルは次のとおりです。

[[270808]]

6.0 その他のエリアメモリ

多くの Java プログラマーはこの分野にほとんど関わりがありません。

実際、NIO など、JDK の多くの低レベル コード API では、

ソース コードを見ると、多くの箇所のコードが Java で記述されておらず、ネイティブ メソッドを使用してローカル オペレーティング システム内のいくつかのメソッド (C 言語で記述されたメソッドである可能性があります) を呼び出していることがわかります。

例: public native int hashCode();

このネイティブ メソッドが呼び出されると、スレッドに対応するローカル メソッド スタックが生成されます。これは実際には Java 仮想マシン スタックに似ています。また、各種ネイティブ メソッドのローカル変数テーブルなどの情報も保存します。

JVM ではない別の領域があります。 NIO の allocateDirect API を使用すると、JVA ヒープ外にメモリ領域を割り当て、Java 仮想マシン スタック内の DirectByteBuffer を使用してオフヒープ メモリ領域を参照および操作できます。

7.0 要約

基本的にJVMのコアメモリ領域の機能がわかりやすく説明されています。ここまで答えられれば、スムーズに面接に合格できるはずです。

メソッド領域、プログラム カウンター、Java 仮想マシン スタック、Java ヒープ メモリといったメモリ領域の機能に注目する必要があります。

<<:  スキルギャップが拡大する中、クラウド時代の企業は主導権を握らなければならない。

>>:  SaaS の将来は人工知能とどのような関係があるのでしょうか?

推薦する

HPは企業のクラウドアプリケーションコストの最適化を支援します

北京、2010 年 1 月 4 日 - HP は最近、企業がクラウド アプリケーションにおける変動コ...

ブランドは春節マーケティングをどのように実施すべきでしょうか?

2017年と比較すると、2018年の春節マーケティングは精彩を欠いていました。毎年1月下旬になると、...

QQマーケティング分析と事例共有

QQ マーケティング手法を使用してユーザーを囲むことができれば、ユーザーが当社の Web サイトや製...

共同購入ウェブサイトの開発:勝利の戦略

2012年から2013年にかけて、共同購入ウェブサイトの数は雨後の筍のように急増しました。国際資本市...

マイクロソフトが2015年にBingで最も人気があった検索のリストを発表

本日、マイクロソフトは、人気のニュースレポート、最も頻繁に検索された有名人、アスリートなどを網羅した...

業界ウェブサイト開発の限界の観点から、新しい業界サイトの発展の道筋を議論する

数年前に業界のウェブサイトを運営し、今日まで続けていれば、ある程度の成功を収めていたでしょう。現在、...

ウェブサイト運営者に必要な認識

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますインターネ...

ブランドH5マーケティング事例分析

パズル探索は、最近非常に人気のあるゲーム タイプです。このタイプのゲームには多くのパズル要素が追加さ...

ウェブサイトが格下げされた理由は、外部リンクの大量投稿に関連している可能性がある。

Baidu は外部リンク、バックリンク、リンクの不正行為を繰り返し取り締まってきたため、最近多くのウ...

#ニュース# Linode が CPU を一日中独占できる新しいスタンドアロン CPU VPS を追加

4 時間前、Linode は最新ニュース「Linode 専用 CPU インスタンス」を正式にリリース...

speedykvm-20% オフ/KVM/$36/年/1g メモリ/50g SSD/1.5T トラフィック/Windows

incero.com データセンター傘下の KVM ベースの VPS ブランドである speedyk...

キーワードを深く理解し、キーワードの価値を深く理解する

検索マーケティングを検索エンジンマーケティングと狭く捉えないでください。実は、アリババもタオバオも検...

柔軟性を高めるために適切なクラウド プラットフォームを選択し、最適化する方法

運用をクラウドに移行することは、IT とビジネスの俊敏性を高めるための課題であることは広く認められて...

国内のネットワーク間決済政策は調整される可能性があり、近い将来に関連する意見が発表される予定である。

12月10日の報道によると、わが国のインターネット相互接続は2012年に初期成果を達成し、ネットワー...

2019年のブランドプロモーションの方向性とチャネル!

2019年はブランディングにとってかなり退屈な年でした。ハイライトとなる事例もいくつか見られますが、...