解讀JVM的組成部分有什么
JVM的組成部分有什么
JVM(Java Virtual Machine)主要由以下幾個(gè)核心組成部分構(gòu)成:
1. 類加載器子系統(tǒng) (Class Loader Subsystem)
職責(zé): 負(fù)責(zé)加載類文件(.class 文件)到 JVM 中。
主要組件:
- 啟動(dòng)類加載器 (Bootstrap Class Loader):
- 負(fù)責(zé)加載 Java 核心類庫(
<JAVA_HOME>/jre/lib
目錄下的 rt.jar、resources.jar 等)。 - 是用 native code(C/C++)實(shí)現(xiàn)的,不是 Java 類。
- 它是所有類加載器的根。
- 負(fù)責(zé)加載 Java 核心類庫(
- 擴(kuò)展類加載器 (Extension Class Loader):
- 負(fù)責(zé)加載 Java 擴(kuò)展類庫(
<JAVA_HOME>/jre/lib/ext
目錄下的 jar 包,或者由java.ext.dirs
系統(tǒng)屬性指定的目錄)。 - 是
sun.misc.Launcher$ExtClassLoader
的實(shí)例。
- 負(fù)責(zé)加載 Java 擴(kuò)展類庫(
- 應(yīng)用程序類加載器 (Application Class Loader/System Class Loader):
- 負(fù)責(zé)加載應(yīng)用程序的類(classpath 下的類)。
- 是
sun.misc.Launcher$AppClassLoader
的實(shí)例。 - 通常是默認(rèn)的類加載器。
- 自定義類加載器 (User-Defined Class Loader):
- 開發(fā)者可以自定義類加載器,繼承
java.lang.ClassLoader
類,實(shí)現(xiàn)特殊的類加載邏輯(例如,從網(wǎng)絡(luò)加載類、從數(shù)據(jù)庫加載類、對(duì)類進(jìn)行加密解密等)。
- 開發(fā)者可以自定義類加載器,繼承
- 啟動(dòng)類加載器 (Bootstrap Class Loader):
類加載機(jī)制:
- 雙親委派模型 (Parent Delegation Model):
- 當(dāng)一個(gè)類加載器需要加載類時(shí),它首先會(huì)委托給它的父類加載器去加載。
- 只有當(dāng)父類加載器無法加載該類時(shí)(在其搜索范圍內(nèi)找不到該類),才由子類加載器嘗試加載。
- 優(yōu)點(diǎn):
- 避免類的重復(fù)加載。
- 保證 Java 核心類庫的安全性(防止用戶自定義的類替換核心類)。
- 加載過程:
- 加載 (Loading): 查找并加載類的二進(jìn)制數(shù)據(jù)(.class 文件)。
- 鏈接 (Linking):
- 驗(yàn)證 (Verification): 確保加載的類文件符合 JVM 規(guī)范,沒有安全問題。
- 準(zhǔn)備 (Preparation): 為類的靜態(tài)變量分配內(nèi)存,并設(shè)置默認(rèn)初始值(零值)。
- 解析 (Resolution): 將類中的符號(hào)引用解析為直接引用(可選,可以延遲到運(yùn)行時(shí))。
- 初始化 (Initialization): 執(zhí)行類的初始化代碼(靜態(tài)變量賦值、靜態(tài)代碼塊)。
- 雙親委派模型 (Parent Delegation Model):
2. 運(yùn)行時(shí)數(shù)據(jù)區(qū) (Runtime Data Areas)
- 職責(zé): JVM 在運(yùn)行 Java 程序時(shí)管理的內(nèi)存區(qū)域。
- 主要區(qū)域:
- 方法區(qū) (Method Area):
- 存儲(chǔ)已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。
- 所有線程共享。
- 在 HotSpot VM 中,方法區(qū)也被稱為“非堆”(Non-Heap)或“永久代”(Permanent Generation,JDK 1.7 及之前)/“元空間”(Metaspace,JDK 1.8 及之后)。
- 運(yùn)行時(shí)常量池 (Runtime Constant Pool): 方法區(qū)的一部分,存放編譯期生成的各種字面量和符號(hào)引用。
- 堆 (Heap):
- 存儲(chǔ)對(duì)象實(shí)例和數(shù)組。
- 所有線程共享。
- 是垃圾回收的主要區(qū)域。
- 可以劃分為新生代(Young Generation)和老年代(Old Generation)。
- 新生代又可以劃分為 Eden 區(qū)、Survivor from 區(qū)和 Survivor to 區(qū)。
- 虛擬機(jī)棧 (VM Stack):
- 存儲(chǔ)方法調(diào)用的局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等信息。
- 每個(gè)線程都有自己的虛擬機(jī)棧,棧的大小可以固定也可以動(dòng)態(tài)擴(kuò)展。
- 如果線程請(qǐng)求的棧深度大于虛擬機(jī)允許的深度,則拋出
StackOverflowError
。 - 如果虛擬機(jī)??梢詣?dòng)態(tài)擴(kuò)展,但無法申請(qǐng)到足夠的內(nèi)存,則拋出
OutOfMemoryError
。
- 本地方法棧 (Native Method Stack):
- 與虛擬機(jī)棧類似,但用于支持 native 方法(使用 C、C++ 等編寫的方法)的執(zhí)行。
- 每個(gè)線程都有自己的本地方法棧。
- 程序計(jì)數(shù)器 (Program Counter Register):
- 記錄當(dāng)前線程正在執(zhí)行的字節(jié)碼指令的地址(行號(hào))。
- 每個(gè)線程都有自己的程序計(jì)數(shù)器。
- 是唯一一個(gè)在 Java 虛擬機(jī)規(guī)范中沒有規(guī)定任何
OutOfMemoryError
情況的區(qū)域。
- 方法區(qū) (Method Area):
3. 執(zhí)行引擎 (Execution Engine)
- 職責(zé): 負(fù)責(zé)執(zhí)行 Java 字節(jié)碼指令。
- 主要組件:
- 解釋器 (Interpreter):
- 逐條解釋執(zhí)行字節(jié)碼指令。
- 啟動(dòng)速度快,但執(zhí)行速度慢。
- 即時(shí)編譯器 (JIT Compiler):
- 將熱點(diǎn)代碼(經(jīng)常執(zhí)行的代碼)編譯為本地機(jī)器碼,提高執(zhí)行效率。
- 編譯需要時(shí)間,但編譯后的代碼執(zhí)行速度快。
- HotSpot VM 中的 JIT 編譯器:
- Client Compiler (C1): 優(yōu)化速度快,但優(yōu)化程度較低。
- Server Compiler (C2): 優(yōu)化速度慢,但優(yōu)化程度較高。
- 分層編譯 (Tiered Compilation): 根據(jù)程序的運(yùn)行情況,選擇不同的編譯器進(jìn)行優(yōu)化(JDK 1.7 引入)。
- 垃圾回收器 (Garbage Collector):
- 負(fù)責(zé)自動(dòng)回收不再使用的對(duì)象,釋放內(nèi)存。
- 不同的 JVM 實(shí)現(xiàn)有不同的垃圾回收器。
- 常見的垃圾回收器:
- Serial GC: 單線程垃圾回收器。
- Parallel GC: 多線程垃圾回收器。
- CMS GC (Concurrent Mark Sweep): 并發(fā)標(biāo)記清除垃圾回收器。
- G1 GC (Garbage-First): 一種面向服務(wù)端應(yīng)用的垃圾回收器。
- ZGC: 一種低延遲垃圾回收器.
- Shenandoah: 一種低延遲垃圾回收器.
- 本地方法接口 (JNI, Java Native Interface):
- 允許 Java 代碼調(diào)用本地方法 (C/C++ 等編寫的方法).
- 解釋器 (Interpreter):
4. 本地庫接口(Native Interface)
- 連接不同的編程語言, 為Java使用非Java代碼編寫的庫提供支持.
JVM 架構(gòu)圖示:
+-----------------------------------------------------------------------------------+ | JVM | +-----------------------------------------------------------------------------------+ | +---------------------+ +------------------------+ +---------------------+ | | | 類加載器子系統(tǒng) | | 運(yùn)行時(shí)數(shù)據(jù)區(qū) | | 執(zhí)行引擎 | | | | (Class Loader) | +------------------------+ +---------------------+ | | +---------------------+ | +------------------+ | | +---------------+ | | | | - 啟動(dòng)類加載器 | | | 方法區(qū) (Method Area) | | | | 解釋器 | | | | | - 擴(kuò)展類加載器 | | +------------------+ | | | (Interpreter) | | | | | - 應(yīng)用程序類加載器 | | | - 運(yùn)行時(shí)常量池 | | | +---------------+ | | | | - 自定義類加載器 | | +------------------+ | | +---------------+ | | | +---------------------+ | +------------------+ | | | 即時(shí)編譯器 | | | | | | | 堆 (Heap) | | | | (JIT Compiler)| | | | | | +------------------+ | | | - C1 (Client) | | | | | | | - 新生代 | | | | - C2 (Server) | | | | | | | - Eden | | | | - 分層編譯 | | | | | | | - Survivor | | | +---------------+ | | | | | | - 老年代 | | | +---------------+ | | | | | +------------------+ | | | 垃圾回收器 | | | | | | +------------------+ | | | (GC) | | | | | | | 虛擬機(jī)棧 (VM Stack) | | | +---------------+ | | | | | +------------------+ | | | | | | | +------------------+ | | +---------------+ | | | | | | 本地方法棧 (Native) | | | |本地方法接口 | | | | | | +------------------+ | | | (JNI) | | | | | | +------------------+ | | +---------------+ | | | | | | 程序計(jì)數(shù)器 (PC) | | | | | | | | +------------------+ | | | | | | +------------------------+ | | | | | | | | +-----------------------------------------------------------------------------------+
總結(jié)
JVM 主要由類加載器子系統(tǒng)、運(yùn)行時(shí)數(shù)據(jù)區(qū)、執(zhí)行引擎、本地庫接口等組成。
- 類加載器負(fù)責(zé)加載類文件。
- 運(yùn)行時(shí)數(shù)據(jù)區(qū)負(fù)責(zé)管理內(nèi)存。
- 執(zhí)行引擎負(fù)責(zé)執(zhí)行字節(jié)碼指令和垃圾回收。
- 本地庫接口負(fù)責(zé)連接其他語言。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java的字符串中對(duì)子字符串的查找方法總結(jié)
這篇文章主要介紹了Java的字符串中對(duì)子字符串的查找方法總結(jié),是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-11-11Java Swing最詳細(xì)基礎(chǔ)知識(shí)總結(jié)
這篇文章主要介紹了Java Swing最詳細(xì)基礎(chǔ)知識(shí)總結(jié),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)Java Swing的小伙伴們有很好的幫助,需要的朋友可以參考下2021-05-05SpringBoot用JdbcTemplates操作Mysql實(shí)例代碼詳解
JdbcTemplate是Spring框架自帶的對(duì)JDBC操作的封裝,目的是提供統(tǒng)一的模板方法使對(duì)數(shù)據(jù)庫的操作更加方便、友好,效率也不錯(cuò),這篇文章主要介紹了SpringBoot用JdbcTemplates操作Mysql2022-10-10JAVA面試題 簡談你對(duì)synchronized關(guān)鍵字的理解
這篇文章主要介紹了JAVA面試題 請(qǐng)談?wù)勀銓?duì)Sychronized關(guān)鍵字的理解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07SpringBoot實(shí)現(xiàn)指標(biāo)監(jiān)控
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)指標(biāo)監(jiān)控方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05示例解析java重載Overloading與覆蓋Overriding
這篇文章主要介紹了java重載Overloading與覆蓋Overriding的示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05Java 邏輯運(yùn)算符中&&與&,||與|的區(qū)別
這篇文章主要介紹了Java中&&與&,||與|的區(qū)別的相關(guān)資料,需要的朋友可以參考下2017-05-05詳談cxf和axis兩種框架下的webservice客戶端開發(fā)
這篇文章主要介紹了詳談cxf和axis兩種框架下的webservice客戶端開發(fā),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08