之前我們已經學習了多線程的相關概念原理以及線程池的管理等,但是要想明白線程的運行過程還需要了解jvm的知識,今天,我們就來介紹一下jvm。
1、什麼是JVM
JVM是Java Virtual Machine(Java虛擬機)的縮寫,每個使用Java的開發者都知道Java字節碼是在JRE中運行(JRE: Java 運行時環境)。JVM則是JRE中的核心組成部分,承擔分析和執行Java字節碼的工作。
它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。JVM有自己完善的硬件架構,如處理器、堆棧、寄存器等,還具有相應的指令系統。Java語言最重要的特點就是跨平臺運行。使用JVM就是爲了支持與操作系統無關,實現跨平臺。所以,JAVA虛擬機JVM是屬於JRE的,而現在我們安裝JDK時也附帶安裝了JRE(當然也可以單獨安裝JRE)。
2、結構
粗略分來,JVM的內部體系結構分爲三部分,分別是:類裝載器(ClassLoader)子系統,運行時數據區,和執行引擎。
類裝載器
每一個Java虛擬機都由一個類加載器子系統(class loader subsystem),負責加載程序中的類型(類和接口),並賦予唯一的名字。每一個Java虛擬機都有一個執行引擎(execution engine)負責執行被加載類中包含的指令。JVM的兩種類裝載器包括:啓動類裝載器和用戶自定義類裝載器,啓動類裝載器是JVM實現的一部分,用戶自定義類裝載器則是Java程序的一部分,必須是ClassLoader類的子類。
執行引擎
主要執行字節碼,或者執行本地方法
主要的執行技術有:解釋,即時編譯,自適應優化、芯片級直接執行其中解釋屬於第一代JVM,即時編譯JIT屬於第二代JVM,自適應優化(目前Sun的HotspotJVM採用這種技術)則吸取第一代JVM和第二代JVM的經驗,採用兩者結合的方式 。
自適應優化:開始對所有的代碼都採取解釋執行的方式,並監視代碼執行情況,然後對那些經常調用的方法啓動一個後臺線程,將其編譯爲本地代碼,並進行仔細優化。若方法不再頻繁使用,則取消編譯過的代碼,仍對其進行解釋執行。
運行時數據區
主要包括:方法區,堆,Java棧,PC寄存器,本地方法棧
方法區和堆由所有線程共享
堆:存放所有程序在運行時創建的對象
方法區:當JVM的類裝載器加載.class文件,並進行解析,把解析的類型信息放入方法區。
Java棧和PC寄存器由線程獨享。JVM棧是線程私有的,每個線程創建的同時都會創建JVM棧,JVM棧中存放的爲當前線程中局部基本類型的變量(java中定義的八種基本類型:boolean、char、byte、short、int、long、float、double)、部分的返回結果以及Stack Frame,非基本類型的對象在JVM棧上僅存放一個指向堆上的地址
3、特性
基於棧(Stack-based)的虛擬機: 不同於Intel x86和ARM等比較流行的計算機處理器都是基於寄存器(register)架構,JVM是基於棧執行的。
符號引用(Symbolic reference): 除基本類型外的所有Java類型(類和接口)都是通過符號引用取得關聯的,而非顯式的基於內存地址的引用。
垃圾回收機制: 類的實例通過用戶代碼進行顯式創建,但卻通過垃圾回收機制自動銷燬。
通過明確清晰基本類型確保平臺無關性: 像C/C++等傳統編程語言對於int類型數據在同平臺上會有不同的字節長度。JVM卻通過明確的定義基本類型的字節長度來維持代碼的平臺兼容性,從而做到平臺無關。
網絡字節序(Network byte order): Java class文件的二進制表示使用的是基於網絡的字節序(network byte order)。爲了在使用小端(little endian)的Intel x86平臺和在使用了大端(big endian)的RISC系列平臺之間保持平臺無關,必須要定義一個固定的字節序。JVM選擇了網絡傳輸協議中使用的網絡字節序,即基於大端(big endian)的字節序。
總結:
今天我們知道了什麼是jvm,以及jvm的結構等,下一次我們將深入剖析一下jvm的原理和工作流程等。