blog

JVMについて知っているのはヒープとスタックだけか?

多くのJavaプログラマは、JVMのランタイムデータ領域について言及し、ヒープとスタックと言うでしょう、もちろん、Javaプログラマは、メソッド領域、仮想マシンスタック、ローカルメソッドスタック、ヒー...

Dec 11, 2020 · 4 min. read
シェア

多くのJavaプログラマはJVMの実行時データ領域について、ヒープとスタックと答えます。もちろん、メソッド領域、仮想マシンスタック、ローカルメソッドスタック、ヒープ、プログラムカウンタと答えるJavaプログラマもいますが、永久世代、仮想マシンスタック、ローカルメソッドスタック、ヒープ、プログラムカウンタと答えるJavaプログラマもいます。では、実際どちらの答えが正しいのでしょうか?

まず、上記の質問に答えるために不可欠な2つの概念を紹介します。1.仮想マシン:簡単に言えば、仮想マシンは抽象的なコンピュータです。2.Java仮想マシン仕様: 仮想マシン仕様はJava仮想マシンに対する制約であり、Java仮想マシンは仮想マシン仕様の実装を担当します。通常JAVA仮想マシンと呼ばれるものは、一般的にHotSpotのようなJAVA仮想マシン仕様の特定の実装を指します。もちろん、市場には他のJava仮想マシンもあります。以下のスクリーンショットはからのものです

JVM6の仕様から、ランタイム・データ領域は、PC Register(プログラム・カウンタ)、Java Virtual Machine Stacks(Java仮想マシン・スタック)、Heap(ヒープ)、Method Area(メソッド領域)、Native Method Stacks(ローカル・メソッド・スタック)、Runtime Constant Pool (ランタイム定数プールとその部分)。赤い部分に注意してください , ランタイム定数プールがメソッド領域にあることがわかります。仕様によると、JVMのランタイムデータ領域は大まかに描画することができます。慎重にJVM6、7、8ランタイムデータ領域の仕様を見た後、ランタイムデータ領域の要件にJVM6、7、8は全く変更されていないか、またはこれらの部分のプログラムカウンタ、Java仮想スタック、ヒープ、メソッド領域、ローカルメソッドスタック、ランタイム定数プール。パーマネント世代は、メソッド領域の別名、またはメソッド領域の実装、正確には。仕様はそう必要なのですが、仮想マシンがこれらの領域を調整するというか、JVMの仕様の実装を調整します。いろいろ調べた結果、パーマネントジェネレーション記述の公式記述はまだ見つかりませんでしたので、ご連絡ください)。多くのブログといくつかの情報を組み合わせた結果、以下のように判断できます。永久生成はHotSpot仮想マシン独自の概念で、HotSpotチームはメソッドエリアのJVM仕様を実装するために永久生成を使用しています。他の仮想マシンでは、このコンセプトのパーマネント生成はありません。jdk8ではパーマネント生成が削除されましたが、この点については後で詳しく説明します。では、なぜメソッド領域をパーマネント世代と呼ぶのでしょうか?これはGCの世代コレクションと関係があり、メモリリカバリはメソッド領域とヒープで発生します。(IDEAでヒープの情報を見るには-XX:+PrintGCDetailsパラメータを使います。コンソールの情報から、ヒープが領域に分割されていることがわかります。 PSYoungGen eden space from space to space ParOldGen PSとParはゴミ収集器の略で、ヒープが若い世代と古い世代に分けられ、ヒープがゴミ収集機構の中心であることを意味します。ヒープがゴミ収集機構の中心であり、若い世代と古い世代に対して、メソッド領域もゴミ収集の範囲に含まれるので、メソッド領域をパーマネント世代と呼びます。これがパーマネント世代の由来です。次に、JVM1.7と1.6の違いを紹介します。JVM1.6と1.7の違いを紹介するにあたり、まずStringクラスのintern()メソッドを紹介します。 このメソッドが呼ばれると、文字列がまだ文字列定数プールの中になければ、文字列は文字列定数プールに追加されます。調べてみたところ、ランタイムデータ領域に関するHotSpotの公式な記述はまだ見つかりませんでしたが、多くのブログで、jdk 1.7では文字列定数プールがヒープに移動したことが指摘されています。以下は1.6と1.8でのテスト例です。 1.6 結果: false 1.7以上 結果: true 理由を説明すると、1.6では文字列定数プールはパーマネント世代に置かれ、ヒープは分離されています。1.6 1.7 VMが調整され、定数プールにオブジェクトのコピーを格納する代わりに、定数プールはそのオブジェクトへの参照をヒープに格納できるようになり、より柔軟になりました。1.7以上のダイアグラム

次の写真を見てください。jdkのバージョンは1.8です。MetaSpaceとは一体何なのでしょうか?

文字列定数プールはヒープに残り、メソッド領域はMetaSpaceに移動します。では、JVM実行時領域はいくつの部分から構成されているのかと聞かれたら、どう答えればいいのでしょうか?JVMの仕様では、JVMの実行時領域は以下のような部分から構成されることになっています:

  1. メソッド領域
  2. java仮想マシンスタック
  3. ローカルメソッドスタック
  4. ヒープ
  5. プログラムカウンタ
  6. ランタイム定数プール しかし、異なるVMは異なる仕様の実装を持っています。HotSpot 1.6のメソッド領域の実装は永久生成と呼ばれ、1.7は文字列定数プールをヒープに移動し、1.8はメソッド領域のメタデータ領域の実装を支持して永久生成を削除し、文字列定数プールはまだヒープにあります。[1]: [2]: www.sczyh30.com/posts/Java/...
Read next

Red Hat Enterprise Linux 7 は間もなく完全にリリースされる。

RHEL 7は昨年12月からベータ版をリリースしており、テスターからは好意的な評価を得ています。今週、Red Hat は RHEL 7 のリリース候補をリリースする予定で、新バージョンではコンテナやカーネルなど、数多くの改良が加えられています。

Dec 11, 2020 · 2 min read