Java仮想マシン(JVM)を読解しながら理解する #07
こちらの記事の続きです
よんでいる公式ドキュメント
先日、人生初のハッカソンに参加してきたのですが。。。
イベントを企画して運営する難しさを体験する1日でした。
企画運営をしてくださった皆さま、ありがとうございました!!
今度は参加者ではなく、企画運営側で携わってみたいな・・・
さて、少し間隔が空いたのですが今回もJVMを読み進めていきます。
2.5.4. Method Area(メソッド領域)
今回もかなり重要そうな項目ですね・・・!!
メソッド領域とは?
•JVM起動時に作成される
•JVM 内で すべてのスレッドに共有されるメモリ領域
•クラスごとの情報 を保持する
(定数プール、フィールド・メソッド情報、メソッド/コンストラクタのコードなど)
•メモリ不足になると OutOfMemoryError が発生
そして、下記内容はJVMの実装者に委ねられる項目です。
•論理的にはヒープの一部だが、GCや圧縮を行わない実装もある
•サイズは固定 or 可変(拡張・縮小できる)
•連続したメモリである必要はない
•ユーザーが初期サイズ・最大/最小サイズを設定できる場合がある
ここまでは、公式ドキュメントに記載されていた内容を要約しただけですが・・・
では、ヒープ領域とメソッド領域は何が違うのか??と疑問になりませんか??🧐
メソッド領域とヒープ領域の違い
気になったので以下の表に差異をまとめました!!
領域 | 格納されるもの | 主な用途 | GC対象か |
---|---|---|---|
ヒープ | new で作られたオブジェクト、配列 | インスタンスのライフサイクル管理 | GCの主な対象 |
メソッド領域 | クラス情報、メソッドコード、定数プール、static変数 | プログラムの構造・設計図を保持 | GCの対象になる場合もあるが、クラスアンロード時にも開放される |
ここまでの内容をまとめると・・・
ヒープは「モノ置き場」、メソッド領域は「設計図置き場」
設計図は普段捨てられないけれど、クラスごとに不要になったときだけ捨てられる
2.5.5. Run-Time Constant Pool(実行時定数プール)
なんかまた直訳だけ意味が分かりそうで、分かりにくそうな項目ですね・・・😇
実行時定数プールとは?
•クラスやインタフェースごとに作られる定数の倉庫
•各実行時定数プールは JVMのメソッド領域 から確保される
•実行時定数プールの構築に必要なメモリをメソッド領域から確保できない場合、JVM は OutOfMemoryError をスロー
んーーー なんかイメージつきそうでつかない・・・😇
とりあえず、先ほど登場したメソッド領域の一部のようですが
具体的に何を管理しているのでしょうか??
メソッド領域と実行時定数プールの違い
領域 | 単位 | 役割 | 主な内容 |
---|---|---|---|
メソッド領域 | JVM 全体で共有 | クラスやインタフェースの「設計図置き場」 | フィールド定義、メソッド定義、バイトコード、static変数、実行時定数プール |
実行時定数プール | クラス/インタフェースごと | 設計図に付属する「辞書・参照リスト」 | 数値リテラル、文字列リテラル、クラス参照、メソッド・フィールド参照 |
なるほど!!
個人的には表にすることで結構納得感がありました。
2.5.6. Native Method Stacks(ネイティブメソッドスタック)
さあ。。。長かった2.5章も最後の項目です!!
公式ドキュメントを翻訳して読んでいるのですが・・・よくわからない項目だったので頑張って読解していきます!!
ネイティブメソッドスタックとは?
•Java 以外の言語(例:C 言語)で書かれた ネイティブメソッドを実行するためのスタック
さあ。。。早速もう謎です😇
今まで実装で触れたことはなかったのですが、native修飾詞ってものが存在するんですね・・・😦
種類 | 実装場所 | 実行方法 | 主な用途 |
---|---|---|---|
普通のJavaメソッド | Java (バイトコード) | JVM が解釈 / コンパイルして実行 | 通常のアプリケーション処理 |
ネイティブメソッド | C / C++ など |
native キーワード + JNI を通じて実行 |
OS機能利用、外部ライブラリ連携、最適化処理 |
※JNI (Java Native Interface) :Java と C/C++ の橋渡しをする仕組み/Java から OS の機能や外部ライブラリを呼び出すときに使う |
エラー時は・・・
•上限超え → StackOverflowError
•メモリ不足 → OutOfMemoryError
そして、
従来のスタックに依存しないJava仮想マシンの実装では、ネイティブメソッドスタックを提供する必要はありません
と直訳で記載されているで、ネイティブメソッドスタックの実装の要否はC言語スタックに依存するかしないかがによって別れるようです。
つまりピュアJavaのみを解釈するJVMではネイティブメソッドスタックの実装は省略できて、
OracleのHotSpot JVMのような一般的な実装では、標準ライブラリ自身がネイティブメソッドを多用しているため、内部的には必ず利用されているということになります。
まとめ
- ヒープ … オブジェクトの「モノ置き場」
- メソッド領域 … クラスやメソッドの「設計図置き場」
- 実行時定数プール … 設計図に付随する「辞書」
- ネイティブメソッドスタック … JVMの外の世界(OS/ライブラリ)とつなぐ「橋渡しスタック」
Discussion