本篇僅僅是JVM的簡介,關於更多的JVM細節,請參見本專題JVM:
計算機系統當中的JVM
- JVM是運行在操作系統之上的,並沒有和硬件有直接的交互
- Java代碼一次編譯,到處運行
HotSpot虛擬機結構概覽

- 方法區和堆區是所有線程共享的內存區域;
- 而java棧、本地方法棧和程序計數器是運行是線程私有的內存區域。
- Java棧又叫做jvm虛擬機棧。
- 方法區(永久代)在jdk8中又叫做元空間Metaspace
- 方法區用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器(JIT編譯器,英文寫作Just-In-Time Compiler)編譯后的代碼等數據。
- 雖然Java虛擬機規范把方法區描述為堆的一個邏輯部分,但是它卻有一個別名叫做 Non-Heap(非堆),目的應該是與 Java 堆區分開來。
- java代碼大致執行流程:java源程序--編譯javac-->字節碼文件.class-->類裝載子系統生成反射類(存入方法區)--->運行時數據區(五大塊兒)--->執行引擎-->解釋執行+編譯執行(JIT)-->操作系統(Win,Linux,Mac JVM)
棧的指令集架構和寄存器的指令集架構
由於跨平台的設計,java的指令都是根據棧來設計的,不同平台CPU架構不同,所以不能設計為基於寄存器的
二者區別:
棧:跨平台性、指令集小、指令多;執行性比寄存器差
寄存器:指令少
一些簡單查看命令:
//查看指令集命令代碼
cd out/production/類根目錄
//反編譯
javap -v StackStruTest.class
//打印程序執行的進程
jps
Hotspot中方法區的變動:
關於方法區的結構,在過去的版本jdk1.6/1.7/1.8當中均有變動,故在此提前聲明:
- jdk1.6及之前:有永久代(permanent generation) ,靜態變量、字符串常量池存放在 永久代上。
- jdk1.7:有永久代,但已經逐步“去永久代”,字符串常量池、靜態變量移除,保存在堆中。注意:
- jdk1.8及之后: 無永久代,類型信息、字段、方法、常量保存在本地內存的元空間,但字符串常量池、靜態變量仍留在堆空間.


注意:
jdk1.8及之后: 無永久代,類型信息、字段、方法、常量保存在本地內存的元空間。
但字符串常量池、靜態變量仍留在堆空間。
除此之外,元空間(或稱方法區),不再使用虛擬機內存,而是使用本地內存。
參見: 關於類加載子系統詳述
參見: 關於程序計數器詳述
參見: 關於本地方法接口詳述
參見: 關於本地方法棧詳述
參見: 關於方法區的詳述
參見: 關於堆區的詳述
參見: 關於執行引擎的詳述
關於更多JVM細節,請參見本專題JVM:
jvm生命周期
1.啟動
通過引導類加載器(bootstrap class loader)創建一個初始類(initial class)來完成的,這個類是由虛擬機的具體實現指定的.
2.執行
- 一個運行中的java虛擬機有着一個清晰的任務:執行Java程序;
- 程序開始執行的時候他才運行,程序結束時他就停止;
- 執行一個所謂的Java程序的時候,真真正正在執行的是一個叫做Java虛擬機的進程。
3.退出
- 程序正常執行結束
- 程序異常或錯誤而異常終止
- 操作系統錯誤導致終止
- 某線程調用Runtime類或System類的exit方法,或Runtime類的halt方法,並且java安全管理器也允許這次exit或halt操作
- 除此之外,JNI規范描述了用JNI Invocation API來加載或卸載Java虛擬機時,Java虛擬機的退出情況
補充:古今JVM
- SUN Classic
- Exact VM
- HotSpot VM :HotSpot指熱點代碼探測技術
- BEA JRockit:(BEA 已被Oracle收購) 專注於服務端應用,世界最快的jvm之一
- IBM J9
- Taobao JVM: 目前已經在淘寶、天貓上線,替換了Oracle官方JVM;
- Graal VM: Oracle 2018年4月公開,口號 Run Programs Faster Anywhere.最可能替代HotSpot的產品
Android虛擬機 DVM
- 谷歌開發,基於Android,在2.2中提供了JIT
- 只能稱作虛擬機 不能稱為java虛擬機,他沒有遵循Java虛擬機規范
- 基於寄存器架構,效率高,但是跟硬件耦合度比較高
- 不能直接執行class文件,執行的是dex文件
- 5.0使用支持提前編譯的ART VM替換Dalvik VM