あなたは本当に 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 の将来は人工知能とどのような関係があるのでしょうか?

推薦する

私は SEO 市場でクライアントを探しています。あなたはどうですか?

ネットワーク関係者というのは、私が今自分につけている肩書きです。インターネットマーケティングプランナ...

マイクロソフト、大規模な組織再編計画を発表:2つの新部門を設立

[[224401]]北京時間3月29日深夜、マイクロソフトは木曜日に大規模な組織再編計画を発表し、「...

Kubernetes ネットワークの 4 つのシナリオの分析

この記事では、コンテナ間、Pod 間、Pod からサービス、外部から内部の 4 つのシナリオにおける...

クラウドコンピューティングの新たなトレンド

急速に進化するクラウド環境において、これらの新たなクラウド トレンドは、コストの最適化、回復力の確保...

あなたは本当に検索エンジンに夢中になりますか?

作者の智怡はつい最近、恋に落ちました。長い間追いかけていた女の子が、ついに私と一緒になることに同意し...

2022年のトップ10消費者市場トラック!

2022年上半期、市場の成長率は鈍化し、消費者の嗜好は「大手ブランドを買うか、コストパフォーマンスを...

百度ランキングにおけるさまざまな要素の割合についての簡単な議論

最近、インターネットで百度ランキングにおけるさまざまな要素の割合についての記事をたくさん見つけました...

5 分間の技術講演 | Xinchuang クラウド デスクトップについてどれくらいご存知ですか?

パート01 Xinchuang Cloud Desktopとは何ですか?クラウド デスクトップは、伝...

外部リンクマーケティングにおける高品質なコンテンツに基づくコンセプトの変更方法

「効果的なクリックリンクを作るには?」友人が私のブログにこの質問を投稿しました。これはまさに、私たち...

JVM の新世代と旧世代のデフォルトの比率は本当に 1:2 ですか?

[[392981]]画像はPexelsより[51CTO.com オリジナル記事]業界の一般的な認識は...

Alibaba Cloud International Editionで海外向けECサイトを構築する場合は、以下の点に注意する必要があります。

クラウド サービス テクノロジーは、企業に明確な競争上の優位性をもたらします。企業がイノベーションと...

「SEO最適化」 - 間違ったSEO用語について考える

SEO は Search Engine Optimization (検索エンジン最適化) の略語です...

ウェブサイトの最適化を3か月続けた後の混乱: ランキングが頻繁に変動する理由

これは私がいくつかのウェブサイトを構築した後のことでした。数か月の運用後、ウェブサイトのランキングは...

ウェブマスターのSEO体験の共有

検索エンジンのアルゴリズムがますます洗練されるにつれて、ウェブサイトの品質に対する要求も高まっていま...

クラウドコンピューティングは人気があるが、クラウドコンピューティングへの支出の無駄に注意する必要がある

[[347963]] 「正しいことをする」と「物事を正しく行う」はほぼ同じ文ですが、単語を入れ替える...