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

推薦する

戦略計画に影響を与えるマルチクラウド ストレージの 6 つの課題

複数のクラウド ストレージ プロバイダーを使用すると、データの保存方法と場所に影響する可能性があるた...

ブランド構築はオンラインマーケティングを成功させるための魔法の武器です

企業の存続と発展は相互補完的であることは誰もが知っています。なぜそう言えるのでしょうか。それは一定の...

ウェブサイトの更新とキーワードランキング

Dianshi フォーラムで誰かが Web サイトの更新について質問しました。私はマット・カッツ氏に...

#UK VPS# piohost - 年間 12.5 ドル/メモリ 1.5g/コア 4 個/ハードディスク 50g/トラフィック 1T

piohost は比較的新しいビジネスのようで、仮想ホスティング、VPS、独立サーバーなどのビジネス...

#黒5# namecheap: ドメイン名登録と移管の割引、仮想ホスティング $8.8/年、メール $3.56/年、SSL 証明書 $2.88/年

今後、Namecheap の製品には大きな割引が適用されます: (1) ドメイン名の登録と転送、複数...

Docker の使用上の注意

著者: jakieli 1. Docker を使用する理由当社では、レポートのプレゼンテーションに社...

クラウド ERP は止められない: Oracle NetSuite の成功を解読する

[オリジナル記事は51CTO.comより] OracleがNetSuiteを93億ドルで買収してから...

アマゾンAWSが中国でスタートアップ国際化プログラムを開始

2018 年 5 月 24 日 – AWS は西安で第 2 回 AWS スタートアップ デーを開催し...

#VietnamVPS# tothost: 月額1.63ドルから、ネイティブベトナムIP、100M帯域幅、無制限トラフィック、VMware/KVM仮想

tothost は 2009 年に設立されたベトナムのサーバー プロバイダーです。主にベトナム VP...

Yiliuba の CTO、Shang Jinyuan 氏: ソーシャルメディアにおけるマイクロマーケティングの視点

月給5,000~50,000のこれらのプロジェクトはあなたの将来です2018年10月3日から5日まで...

オンラインビデオ業界、テレビドラマの購入に価格上限を設ける計画

ビジネスデイリー(記者 江夢偉)動画サイトが購入するドラマや映画の価格は今年も引き続き下落しているが...

ウェブサイトの最適化で注意すべきいくつかの側面

インターネットの発展に伴い、ウェブサイトの最適化に注目する企業が増え、ウェブサイトの最適化作業に従事...

ユーザーエクスペリエンスの究極的な分析により、コアランキングアルゴリズムが明らかになる

ユーザーエクスペリエンスに関する記事をたくさん読んだことがあるかもしれません。しかし、この記事を注意...

有名なウェブサイトもユーザーエクスペリエンスを向上させるために新機能を追加している。

今日、パソコンの電源を入れたら暇だったので、ずっとインターネットをブラウズしていました。突然、新しい...

Zhaopin.comのIPO:内部紛争を乗り越え、宴会後に涙を流す

[要約] Zhaopin.com は投資家に想像の余地を与えることができず、その将来の市場価値は暗く...