Java Virtual Machine 官方介紹
Java虛擬機規范官方文檔
https://docs.oracle.com/javase/specs/index.html
其中以java8的為
https://docs.oracle.com/javase/specs/jvms/se8/html/index.html
看下官方的介紹的一節
The Java Virtual Machine Java虛擬機是Java平台的基石。是java實現硬件和操作系統的獨立性(也就是無關性),生成極小體積的編譯代碼,以及保護用戶免受惡意程序攻擊的的關鍵技術組成部分。 Java虛擬機是一種抽象計算機器。像真正的計算機一樣,它有一個指令集以及在運行時各種內存區域。 使用虛擬機實現編程語言是相當普遍的; 最著名的虛擬機可能是 P-Code machine of UCSD Pascal. Java虛擬機的第一個原型實現是在Sun Microsystems inc.完成的,它在手持設備上仿真實現了Java虛擬機指令集,該設備類似於現在的個人數字助理(PDA)。Oracle現在已經將許多java虛擬機實現應用於 移動設備 pc 服務器等領域,但是Java虛擬機不局限於任何特定的實現技術、主機硬件或主機操作系統。也不局限於特定的代碼執行方式,雖然不強求使用解釋器來執行程序,但是也可以通過將它的指令集編譯成一個實際的CPU來實現。它也可以在微代碼microcode實現,也可以直接在CPU中實現。 Java虛擬機對Java編程語言一無所知,只知道一種特定的二進制格式,class文件格式。一個class文件包含Java虛擬機指令集(或者稱之為字節碼bytecode)和符號表,以及其他輔助信息。
基於安全方面的考慮,Java虛擬機在class文件中施加了許多強制性的語法和結構化約束,凡是能用class文件正確表達出來的編程語言,都可以放在Java虛擬機里面執行。由於它是一個通用的、機器無關的執行平台,所以其他語言的實現者都可以考慮將Java虛擬機作為那些語言的交付媒介。
|
java的組成部分
- Java語言規范
- Java 應用程序編程接口 API
- Java class文件格式規范
- Java虛擬機
java語言規范
java語言規范決定了你要怎么書寫你的源代碼
也就是java的語法句法詞法結構組成,數據類型長度等,對於java語言本身的描述
比如主函數需要時public static void main(String[] args){ 為什么使用public而不是common表示公用?這就是java語言規范的作用
java應用程序編程接口
Java應用程序API 也就是java設計者提供的基本的功能方法,比如訪系統資源
API之主要目的是提供應用程序與開發人員以訪問一組例程的能力,而又無需訪問源碼,或理解內部工作機制的細節。
提供API所定義的功能的軟件稱作此API的實現。API是一種接口,故而是一種抽象。
應用程序接口為:"電腦操作系統(Operating system)’或‘程序庫’提供給應用程序調用使用的代碼
其實所有的功能也都是依賴操作系統本身的,比如讀取文件,獲取文件的屬性
如果一個操作系統,本身就沒有網絡通信的功能,你是不可能在上面完成網絡通信程序的開發的
Java class文件格式規范
編譯后被Java虛擬機執行的一種二進制文件格式
這是一種統一的明確的格式 一般以文件的形式存儲
其實就是java虛擬機的"機器語言"
Java虛擬機
讀取class文件,解析class文件並執行,實際運行java的機器
一種抽象化的計算機,通過在實際的計算機上仿真模擬各種計算機功能來實現的。
編寫任何一個程序你都會用到這四個技術領域
無關與相關的辯證關系
JVM是平台相關的,不同的平台有不同的虛擬機
但是她在不同的平台上提供統一一致的JVM虛擬指令集,對具體的平台進行抽象封裝
不管運行在何種平台,他們提供一致性的操作與訪問形式
從JVM本身的平台相關性,轉變成為JAVA語言的平台無關性
class文件是源代碼編譯后的 平台無關的 二進制文件格式,
不依賴於特定的硬件與操作系統表示形式
是JVM可以識別執行的語言,相當於JVM的機器語言
也就是說,不管何種語言,如果一旦能夠編譯成為符合規范的class文件格式
就能夠被JVM進行執行! 這就相當於實現了語言無關性
可以說,java設計者的野心很大, class文件 與JVM的結合,語言無關加上平台無關
java語言實現與運行原理
再回頭看下java技術體系,可以很清晰的看得出來
java的語言實現與運行原理
Java語言規范 和 Java 應用程序編程接口 API 提供了使用Java語言解決問題的方式
Java class文件格式規范 和Java虛擬機 則約定了Java的運行原理
class文件是對源代碼的編譯,不僅僅具有語言無關性的好處
源代碼是以對人友好的方式,class文件是機器友好的,通過對原始文件進行特殊的處理與轉換,能夠提高運行的性能,將一部分工作前置
class文件既然是對於源代碼的轉換描述
自然是會涉及到java中的各種數據類型,方法調用,常量等等的描述與表示
JVM既然是解析class文件進行解析執行,自然是需要解析class文件,並且能夠讀取驗證文件的格式以及語法格式,然后進行裝載運行
所以說想要了解Java的運行原理
最基本的兩個部分就是class文件的結構組成以及JVM的運行區域內存的管理
Java語法中所有的一切都要能夠表示出來
比如數據類型 引用類型還是基本類型 字段屬性 方法 公有私有 靜態 非靜態 如何表示描述
以及必要的信息,比如當前對象的this等等
某種程度上來說 class文件就是源代碼針對於java虛擬機的"注解版" ,將你知道的語法表示出來
然后還有潛在的隱藏的信息,比如父類信息等
對於一個已經定義好的class文件,JVM需要進行一系列嚴格的驗證
因為一個class文件可能不是由一個標准的編譯器生成的也可能被別人惡意篡改過
所以JVM必須驗證
驗證之后還需要進行裝載把數據信息裝載到內存中,然后進行初始化等等
這就是JVM涉及到的部分
所以說想要弄明白java的運行原理需要了解清楚class文件的結構以及JVM的運行內存划分
使用javap查看編譯后的文件
源代碼
javap -v HelloWolrd.class 查看

上圖中的信息不必較真,我也是隨便標注了個別比較好辨別的點
但是你完全可以發現
class文件對於源文件的完整表述,類信息,字段信息 方法信息 涉及到的常量與其他類的調用等等
class文件是一張巨大的表
信息是單獨存放的,可以把行號#XXX 理解成地址,
如下圖所示,從頭不斷地根據地址信息串聯起來,知道最終的葉子數據信息,形成一張巨大的信息表
比如

再次重申,這些就相當於JVM的機器語言了,有數據,有指令,JVM要做的就是解析執行了
當然,是一項很復雜的工作
另外javap還有很多其他命令