🤖

Java仮想マシン(JVM)を読解しながら理解する #01

に公開

最近TECH WORLDさんのショート動画で『情熱プログラマー』について話していた動画を拝見して、
本屋さんでとりあえず購入してみたのがこの記事を執筆したきっかけです。

https://youtube.com/shorts/canHViPJlmo?si=I56UiMOCif5dv_Bw

まだ読み終えてはいないですが、
第1章.8 『スペシャリストになろう』を読んだ時に衝撃を受けたのでそこから少しづでも勉強しようと思いこの記事の作成に着手しました。

Javaの仮想マシンをクラッシュさせるプログラムをピュアJavaで書くとしたらどんな手段をつかいますか?

🤔??
全く何も返答が思いつかない。。。

著者の見解としては、『自己採点が高いJavaエンジニアであればJVMがクラッシュさせるような間違ったプログラミングトリックが思いつかないはずがない』
と思って面接時に聞いていたそうです。

自己採点が高いJavaエンジニアではないですが、
いかに日常的に触っている Javaを知らないのか を突きつけられたと感じたので手始めに、
Oracle社の公式ドキュメント『Java仮想マシン仕様』を読解してJVMの理解を深めていこうと思います。
何回に分けて記載するのかなど規模感も把握できていない状態ではあるが、自分の理解の整理として記録していきますが誰かしらの助けになることがあるのであれば幸いです。

https://docs.oracle.com/javase/specs/jvms/se17/html/index.html

1.1. A Bit of History(歴史のほんの一部)

ここは歴史項目なのでさらっと流しますが、
主にHotJavaについて記載がされていました。

ドキュメントを読んで初めてしった『HotJava』ですが、
どうやら今でいうJSのようにブラウザ側でJavaを実行できる画期的なブラウザだったそうです。

YouTubeで調べてみると、いくつか参考になりそうな動画が出てきたので共有しておきます。

https://youtube.com/shorts/ICpasGFJTQ8?si=4DmxS6ObiOEcMmR3

https://youtube.com/shorts/x70m3IMF9Ic?si=ItGhZvknHc1RDtje

NetscapeがJavaScriptをリリース(1995年末)する約1年前にサン・マイクロシステムズが開発が開発していたそうです。
結果的に、

  • Javaアプレット+JVM起動にメモリを多く消費
  • Javaアプレットはローカルにコードを実行するため、サンドボックスをすり抜ける脆弱性が次々に発覚

※Javaアプレット:Webブラウザ上で実行されるJavaプログラムのこと

などがあり、Flash、Ajaxなどの登場もあって商業的には廃れていったようです。

JSの開発時にブラウザ上でデバッグしていても頻繁にVMが走っているのを見かけますが、
そのVMの発想はもしかしたらJVMの影響を受けていたのかもしれません・・・

chatGPTにも質問したら以下のような回答が返ってきました。

1.2. The Java Virtual Machine(Java仮想マシン)

やっと本題のJVMについてです。
このドキュメントを読んでいて一番衝撃的だったのは・・・・
『Java仮想マシンはJavaプログラミング言語そのものについては何も知らず。。。。。』
と記載があったことでした。

何となく名前が『Java仮想マシン/JVM』だったのでJavaを読み込んでそうな認識がなぜかありましたが・・・・
確かにjavacコマンドでコンパイルしている・・・つまり、
Javaからバイトコードに変換して、その後VMが実行されるのでJavaをVMが読み込む必要がないので今更ながらに納得しました。

一応フローで整理しておきます。

[1] Javaソースコードを書く(Hello.javaを実装したとする)
       ↓
[2] javac Hello.java
       ↓
[3] Hello.class(2のコマンドでバイトコード生成される)
       ↓
[4] java Hello(JVMで3のバイトコードを実行)
       ↓
[5] JVMが解釈実行する

さらに、ドキュメントには以下の説明が続きます。
セキュリティ上の理由から、Java仮想マシンはclassファイル内のコードに強力な構文的および構造的制約を課します

なるほど・・・
コンパイルの時にもチェックを色々確認しているはずなのに、JVM実行時にも再度何をチェックするのか?? 冗長がセキュアなのか?? 気になったので少し調べてみました。

検証タイミング 検証対象 目的
javac コンパイル時 Javaソースコード プログラマーの書いたコードが Java 言語仕様に準拠しているかを確認
JVM 実行時 (Verifier) class ファイル(バイトコード) そのバイトコードが安全・整合的で、信頼できるものかを検証(第三者由来でも)

なるほど・・・
あくまでコンパイル時は、Javaの言語仕様観点でしかチェックをしていないので、
JVM実行時にもチェックが必要ってことですね!

「開発者の検証」と「実行環境の検証」は役割が異なるようにする(責任分離の原則)
も重要な概念かもしれないですね。

chatGPTは以下のような例えを返してきていました。

第一章の1.3~1.5の項目は、以下内容だったため割愛します。

  • 後続の章についての説明
  • 表記方法
  • フィードバック

まとめ

まだ第1章しか触れていない(序章)ですが、すでに そうなんだ・・・ の連続でした。
まだまだ知らないことだらけなのでこれを機に頑張ってJVMの読解を継続していこうと思います!!

得た知見

  • JVMはJavaを知らない。知っているのはclassファイル(バイトコード)のみ。
  • コンパイル時とJVM実行時には異なる観点でのチェックをしている。
  • JVM/VMの誕生背景には、HotJavaのような革新的な取り組みがあった。

Discussion