🤖
Java仮想マシン(JVM)を読解しながら理解する #4
こちらの記事の続きです。
よんでいる公式ドキュメント
2.5. Run-Time Data Areas(ランタイムデータ領域)
JVMがJavaプログラムを実行する際、データを保持するための領域は大きく以下の2つに分かれます。
| 種類 | 作成タイミング | 破棄タイミング | 主な用途 |
|---|---|---|---|
| JVM起動時に作成(共有) | JVM開始時 | JVM終了時 | メソッド領域、ヒープなど |
| スレッドごとに作成(個別) | スレッド開始時 | スレッド終了時 | PCレジスタ、JVMスタック、ネイティブメソッドスタック |
2.5.1. The pc Register(pcレジスター)
まず。。。。
pc(プログラムカウンタ)とは??から読解していきます!!
プログラムの「どこを実行しているか」を示す 命令のアドレス(位置) を保持する場所
JVMでは、現在実行中のバイトコード命令の位置 が記録される
プログラムカウンタが更新されることで、次に実行する命令が決まる
とのことです。
1. スレッドごとに専用のPCレジスタ
- JVMはマルチスレッド実行が可能。
- 各スレッドは独立した実行経路を持ち、並行して命令を進める。
- そのため、スレッドごとに**「現在の命令位置」**を記録する必要がある。
- この役割を担うのがPCレジスタ。
- メリット:スレッド切り替えが発生しても、他スレッドの実行位置が混ざらない。
2. Javaメソッド実行中はバイトコードの位置(オフセット)を保持
- Javaソースはコンパイルされてバイトコードとなり、メソッド単位で実行される。
- PCレジスタは、**現在実行中のバイトコードの命令位置(オフセット)**を保持。
-
例:
0x0015→ メソッド内の16番目の命令。 - 命令を1つ実行するたびにPCレジスタが更新され、次に実行すべき命令が決まる。
3. nativeメソッド実行中は値が未定義
-
nativeメソッドは、JavaではなくC/C++などのネイティブコードで実装。 - この間、JVMのバイトコード実行サイクルは一時停止。
- PCレジスタに「バイトコード位置」という意味のある値を保持できないため、未定義となる(仕様で許容されている)。
4. JVM実装依存の要素
- PCレジスタの概念はJVM仕様で定義されているが、
- メモリ上での表現方法
- ビット幅
-
実装方法(ハードウェアレジスタ使用 or メモリ変数)
はJVM実装(HotSpot、OpenJ9、GraalVMなど)に依存。
- 実機CPUのレジスタを直接使うケースもあれば、専用の変数で管理するケースもある。
上記内容から
スレッド切り替えがあっても、それぞれのPCレジスタが位置を記録しているため、中断した場所から正確に再開可能 になっています。
次は。。。レジスタ(Register)です!!
レジスタは、CPUや仮想マシンが持つ非常に高速にアクセスできる小さな記憶領域
CPUや仮想マシンが今すぐ必要なデータを置いておく場所
これらの内容を踏まえると・・・
pcレジスタ: 「今どこを実行しているか」を覚えておく場所
と理解しました。
そして、中身や記憶領域の置き場所はJVMの作り手が自由に設計できるため、同じJavaプログラムでもJVMの種類によって内部のPCレジスタの構造は異なるとのこと。
まだランタイムデータ領域の章は続きますが、今日はこのへんで切り上げます🙇
まとめ / 得た知見
- PCレジスタは、JVMにおける「現在実行中の命令位置」を保持する領域であり、プログラムの進行を管理する役割を持つ
- 各スレッドに専用のPCレジスタが存在し、マルチスレッド実行時でも他スレッドの進行位置と干渉せず、中断地点から正確に再開可能
- Javaメソッド実行中はバイトコードの位置を記録し、命令ごとに更新される
- PCレジスタはJVM仕様で概念のみ定義され、内部表現(メモリ管理方法、ビット幅、ハードウェアレジスタ利用の有無など)はJVM実装(HotSpot、OpenJ9、GraalVMなど)に依存。
- レジスタは高速アクセス可能な記憶領域であり、PCレジスタはその中でも「今どこを実行しているか」を記録することに特化している
Discussion