概覽
從 JVM 的總體上看,它解決了3個問題:
- Java 程序的內(nèi)存管理(GC & 運(yùn)行時數(shù)據(jù)區(qū))。
- Java Class 二進(jìn)制字節(jié)流的加載(ClassLoader)。
- Java 程序的執(zhí)行(執(zhí)行引擎)。
如下圖所示:

在我們的日常開發(fā)中,最和我們息息相關(guān)的就是1和2了,比如 GC 調(diào)優(yōu),內(nèi)存故障排查,再比如使用自定義的類加載器去實現(xiàn)一些特定的邏輯,就如我們之前分析的 tomcat 源碼中的類加載器用于隔離不同版本的相同類庫,必須要使用自定義的類加載器。
1. Java 程序的內(nèi)存管理(GC & 運(yùn)行時數(shù)據(jù)區(qū))
1.1. 運(yùn)行時數(shù)據(jù)區(qū)
從上圖中可以看出,虛擬機(jī)內(nèi)存管理主要由幾個部分組成:
- Java 堆(存放對象的地方)
- Java 棧(在 HotSpot 實現(xiàn)中,本地方法棧和虛擬機(jī)棧合二為一)
- PC 寄存器(也稱為程序計數(shù)器)
- 方法區(qū)(JDK8 中已經(jīng)將方法區(qū)去除,改為元數(shù)據(jù)區(qū),解決了方法區(qū)----也稱為永久代的內(nèi)存溢出)。
- 直接內(nèi)存(大小不限制于 Java 堆,直接向操作系統(tǒng)申請,使用場景于讀寫頻繁的場合,例如 NIO)
1.2. 垃圾回收系統(tǒng)
Java 程序員之所以不需要顯式的釋放內(nèi)存,一切都?xì)w功于 GC,GC 解放了 Java 程序員的雙手。GC 系統(tǒng)會在后臺清除無用的實例對象,釋放內(nèi)存空間。
而 JVM 中的 GC 可謂是一個龐大的系統(tǒng),其中分為幾個部分:
- 判斷什么是垃圾對象
- 垃圾回收算法
- 各種各樣的垃圾收集器
我們將會在后面慢慢講解。
2. Java Class 二進(jìn)制字節(jié)流的加載(ClassLoader)
2.1 類加載器
對于 Java 虛擬機(jī)來說,Class 文件是一個重要的接口,無論使用何種語言進(jìn)行軟件開發(fā),只要能將源文件編譯為正確的 Class 文件,那么這種語言就可以在 Java 虛擬機(jī)上運(yùn)行??梢哉f,Class 文件就是虛擬機(jī)的基石。
如圖所示:

從上圖可以看出,虛擬機(jī)不拘泥于 Java 語言,任何一個源文件只要能編譯成 Class 文件的格式,就可以在JVM 上運(yùn)行!Class 文件格式就像是一個接口,只要遵守這個接口,就能夠在 JVM 上運(yùn)行。
2.2 類加載器的工作流程
Class 文件通常是以文件的方式存在(任何二進(jìn)制流都可以是 Class 類型),但只有能被 JVM 加載后才能被使用,才能運(yùn)行編譯后的代碼。系統(tǒng)裝在 Class 類型可以分為加載,鏈接和初始化三個步驟。其中,鏈接也可分為驗證,準(zhǔn)備和解析3步驟。如圖所示:

2.3 類裝載的條件
JVM 不會無故裝載 Class 文件,只有在必要的時候才裝載,哪幾個時候呢?
- 當(dāng)創(chuàng)建一個類的實例是,比如使用 new 關(guān)鍵字,或者通過反射,克隆,反序列化。
- 當(dāng)調(diào)用類的靜態(tài)方法時,即當(dāng)使用字節(jié)碼 invokstatic 指令。
- 當(dāng)使用類或接口的靜態(tài)字段時(final 常量除外),比如,使用 getstatic 或者 pustatic 指令。
- 當(dāng)時用 Java.lang.reflect 包中的方法反射類的方法時。
- 當(dāng)初始化子類,要求先初始化父類。
- 作為啟動虛擬機(jī),含有 main()方法的那個類。
以上6種情況屬于主動調(diào)用,主動調(diào)用會觸發(fā)初始化,還有一種情況是被動調(diào)用,則不會引起初始化。
2.4 類加載器的雙親委派模型
先來看一個著名的圖:

虛擬機(jī)為了保護(hù)應(yīng)用程序內(nèi)出現(xiàn)多個類名相同的類對象,因此發(fā)明了這個機(jī)制:當(dāng) JVM 需要適用一個類時,在判斷類是否已經(jīng)被加載時,會先從當(dāng)前底層類加載器進(jìn)行判斷。當(dāng)系統(tǒng)需要加載一個類時,會從頂層類開始加載,依次向下嘗試,知道成功,否則拋出ClassNotFound 異常。
# 總結(jié)
這篇文章主要是為了后面的詳細(xì)文章做一個大綱,因此只是講述以 JVM 的一些基本的框架和概念,后面講詳細(xì)的講述內(nèi)部細(xì)節(jié)。讓我們學(xué)習(xí)虛擬機(jī)更加的有條理。