Java虛擬機

Java虛擬機（Java Virtual Machine，縮寫：JVM），一種能夠執行Java位元組碼的虛擬機器，以堆疊結構機器來實作。最早由昇陽電腦所研發並實現第一個實現版本，是Java平臺的一部份，能夠執行以Java語言寫作的軟體程式。

Java虛擬機有自己完善的硬體架構，如處理器、堆棧、寄存器等，還具有相應的指令系統。JVM屏蔽了與具體作業系統平台相關的資訊，使得Java程序只需生成在Java虛擬機上運行的目標代碼（字節碼），就可以在多種平台上不加修改地運行。通過對中央處理器（CPU）所執行的軟體實作，實現能執行編譯過的Java程序碼（Applet與應用程式）。

作為一種程式語言的虛擬機，實際上不只是專用於Java語言，只要生成的編譯文件符合JVM對載入編譯文件格式要求，任何語言都可以由JVM編譯運行。此外，除了甲骨文公司提供的Java虛擬機，也有其他開源或閉源的實現。

## 技術規範

據技術規範所述，Java虛擬機是一部抽象（虛擬）的電腦。但技術規範未定義使用的垃圾回收演算法及優化Java虛擬機指令的內部演算法，這主要是為了不給實現者帶來過多困擾與限制。所有的Java程序僅可在對Java虛擬機的抽象技術規範的具體實現環境中才可運行。

自Java平台標準版（J2SE）5.0起，Java虛擬機的技術規範改為由Java社區流程開發制定（JSR 924）。2006年，JSR 924對技術規範進行了變更，支持更改class (文件格式)的提議（JSR 202）。Java虛擬機的技術細節以藍皮書的形式發布，其前言稱：

我們希望這份文檔中的技術規範足以打造出相兼容的淨室版Java虛擬機實現。甲骨文公司提供用於驗證Java虛擬機實現是否正常運作的測試項目。

甲骨文公司的一款Java虛擬機名為HotSpot；另一款自BEA Systems繼承而來的名為JRockit。淨室設計版Java實現有Kaffe、IBM J9及Skelmir's CEE-J。甲骨文公司擁有Java商標權，且可能將其用於認證其他實現是否能完全匹配甲骨文的技術規範。

### 類加載器

Java字節碼的組織單位之一是類。類加載器實現必須識別並加載任何為Java類格式的文件。任何實現也可識別其他二進位文件，但必須識別類文件。

類加載器以下列嚴格順序執行三個基礎任務：

- 加載：尋找並導入特定類型的二進位數據。
- 連結：執行驗證、準備及（可選）解析操作。
- 驗證：確保導入類型的正確性。
- 準備：為類變量分配記憶體並初始化記憶體為默認值。
- 解析：將類型的符號引用轉化為直接引用。
- 初始化：調用初始化類變量至正確起始值的Java代碼。

通常而言，共有兩種類加載器類型：引導類加載器（Bootstrap Class Loader）及使用者定義類加載器（User Defined Class Loader）。

每款Java虛擬機實現均必須有加載受信類的引導類加載器。Java虛擬機技術規範不對類加載器尋找類的方式作出指定。

### 虛擬機架構

Java虛擬機以原始值（整數及浮點數）及引用的方式運行，其本質上是一個32位的機器。64位的`long`和`double`類型數據被原生支持，但需要在幀的局部變量或操作數棧中占用兩個存儲單元（單個單元為32位）。`boolean`、`byte`、`short`及`char`均為符號擴充類型（`char`使用零擴展），且以32位整數的形式（與`int`類型相同）運作。較小的數據類型僅有少量用於載入、存儲於類型轉換的特定指令。`boolean`類型被視為8位`byte`值，0代表`false`，1代表`true`。（雖然《Java虛擬機規範第二版》闡明`boolean`被認為是一種數據類型，但除類型特徵的名字修飾及boolean陣列類型外`boolean`和`byte`無太大區別。`boolean`類型的方法簽名為`Z` 而`byte`的類型簽名為`B`。布爾型陣列搭載數據類型`boolean[]`，但每個元素使用8個字節，同時Java虛擬機不內置將布爾數據包裝成位數組的功能，除此之外其與`byte`陣列大同小異。在其他用途中，Java虛擬機實際上不知道`boolean`類型，因為用於操作布爾型數據的指令與操作`byte`的指令完全相同。）

Java虛擬機擁有用於存儲對象及陣列的垃圾回收堆。代碼、常量及其他類數據均存儲於「方法區」中。方法區邏輯上是堆的一部分，但虛擬機的實現可能會區分兩者，從而可能不對方法區進行垃圾回收。每個Java虛擬機線程均有其自己的調用棧（Java虛擬機棧），用於存儲幀。當調用方法時，Java虛擬機將新建一個幀；方法退出時，幀將自動消除。

每幀均提供一個「操作數棧」及一個「局部變量」陣列。操作數棧用於計算操作數和接收被調用方法的返回值，而局部變量與寄存器的用途相同，也用於傳遞方法參數。故Java虛擬機既是堆棧機器，也是寄存器機。

### 字節碼指令

Java虛擬機擁有進行下列任務的指令集：加載與存儲、算術、類型轉換、創建並控制對象、操作數棧管理（放入及拉出）、控制轉移（分支）、方法調用並返回、拋出異常、基於監視器的並發。

指令集存在的目的是為了保證二進位文件的兼容性。每個獨立宿主作業系統需要對Java虛擬機及運行時環境的不同實現。這些Java虛擬機以相同方式語義解析字節碼，但具體實現可能有所不同。比模擬字節碼更複雜的是在兼容且高效的情況下實現必須映射至不同的宿主作業系統的Java類庫。

上述指令集通過操作共同的抽象數據類型執行命令，而非以使用特定指令集架構的原生數據類型的方式運行。

### Java虛擬機語言

Java虛擬機語言是指使用Java虛擬機託管的有效類文件來表示功能的任意程式語言。類文件中含有Java虛擬機指令集（Java字節碼）、符號表及其他輔助資訊。類文件是用於表達編譯後的類及接口的二進位格式，與硬體及作業系統無關。

市面上有多種Java虛擬機語言，既有移植至Java虛擬機的舊語言，也有全新的語言。JRuby及Jython可能為最知名的移植語言之二；除此之外，也有從零編寫的全新語言，如熱門的Clojure、Apache Groovy、Scala及Kotlin。Java虛擬機語言的一大顯著特徵是都語言互操作性，舉例來說，Scala庫可與Java程序互用，反之亦然。

Java 7虛擬機在Java平台上實現了《JSR 292：動態類型語言支持》。此特性由達文西機器項目開發完成，旨在延伸Java虛擬機的功能，進而支持除Java外的其他語言。

## 語言實現

由於JVM並不是專為Java所實現的運行時，實際上只要有其他程式語言的編譯器能生成正確Java bytecode文件，則這個語言也能實現在JVM上運行。

以下為原生就在JVM上實現運行的語言：

- BBj
- BeanShell
- Ceylon
- Clojure
- Fantom
- Groovy
- Java
- Kotlin
- MIDletPascal
- Scala
- Xtend

以下為實現了相應的JVM編譯器的語言及其編譯（解釋）器，意味著下列語言可以使用基於Java開發的編譯器進行編譯或解釋：

- Erlang：Erjang
- JavaScript：Rhino
- Pascal：Free Pascal
- PHP：Quercus (軟體)
- Python：Jython
- REXX：NetRexx
- Ruby：JRuby
- Scheme：Kawa
- Tcl：Jacl

## 基本資料

- 設計師：昇陽電腦
- 字長/暫存器資料寬度：32位
- 始創時間：1994
- 類型：堆疊結構及加載/存儲體系架構
- 位元組序：大
- 通用暫存器：每個方法的操作數棧（至多65535個）及方法中的局部變量（至多65535個）