最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

面試必問的Java 運行時架構(gòu)JVM詳解

 更新時間:2026年04月27日 09:18:20   作者:Resky0818  
本文主要介紹了Java虛擬機(JVM的結(jié)構(gòu)、運行時數(shù)據(jù)區(qū)、執(zhí)行引擎等相關(guān)知識,JVM主要由類加載器、運行時數(shù)據(jù)區(qū)、執(zhí)行引擎和本地接口等組成,感興趣的朋友跟隨小編一起看看吧

我剛學(xué) Java 的時候,以為 JVM 就是個"黑盒",代碼寫完往里一扔就能跑。

后來才知道,JVM 里面學(xué)問大了去了。

今天這篇文章,就是我復(fù)習(xí) JVM 時整理的筆記。面試問到 JVM 結(jié)構(gòu),如果你只能說出"堆和棧",那大概率要被追問到懷疑人生。

一、先畫個整體框架

在說每個組件之前,先把 JVM 的結(jié)構(gòu)捋清楚。

記住這個圖,這是整個 JVM 的骨架。

三個核心模塊:

  • 類加載器(ClassLoader)—— 把 class 文件加載進來
  • 運行時數(shù)據(jù)區(qū)(Runtime Data Area)—— 分配內(nèi)存,存數(shù)據(jù)
  • 執(zhí)行引擎(Execution Engine)—— 執(zhí)行字節(jié)碼指令

二、類加載器 ClassLoader

它干什么的?

ClassLoader 負責(zé)把 .class 文件(字節(jié)碼)加載到內(nèi)存中,轉(zhuǎn)換成 JVM 能認識的數(shù)據(jù)結(jié)構(gòu)。

加載流程:

.java 源文件
 ?  ↓ 編譯
.class 字節(jié)碼文件
 ?  ↓ ClassLoader
內(nèi)存中的 Class 對象(java.lang.Class)

三個階段

1. 加載(Loading)

  • 通過類的全限定名找到 class 文件
  • 把字節(jié)流轉(zhuǎn)換成方法區(qū)的數(shù)據(jù)結(jié)構(gòu)
  • 在堆里生成一個 Class 對象,作為訪問入口

2. 鏈接(Linking)

  • 驗證:檢查字節(jié)碼格式是否正確(安全檢查)
  • 準備:給靜態(tài)變量分配內(nèi)存,設(shè)置默認值
  • 解析:把符號引用替換成直接引用(比如把"方法名"變成內(nèi)存地址)

3. 初始化(Initialization)

  • 執(zhí)行靜態(tài)代碼塊和靜態(tài)變量的賦值
  • 這是真正執(zhí)行代碼的地方

雙親委派模型

這塊是面試高頻追問。

三層類加載器:

加載器負責(zé)加載例子
Bootstrap ClassLoaderJDK 核心類String, Object
Extension ClassLoaderJDK 擴展類javax.*
Application ClassLoader用戶 classpath自己寫的類

雙親委派流程:

加載請求
 ?  ↓
ApplicationClassLoader
 ?  ↓ 問爸
ExtensionClassLoader
 ?  ↓ 問爸
BootstrapClassLoader
 ?  ↓ 找不到
ExtensionClassLoader 嘗試加載
 ?  ↓ 找不到
ApplicationClassLoader 嘗試加載
 ?  ↓ 成功
返回 Class

為什么這樣設(shè)計?

我當(dāng)初也被問懵了,后來想明白了一個例子:

如果你自己寫一個 java.lang.String,沒有雙親委派的話,JVM 就會加載你自己寫的 String,安全性全沒了。

雙親委派保證:核心類庫優(yōu)先被 Bootstrap 加載,防止用戶代碼覆蓋 JDK。

三、運行時數(shù)據(jù)區(qū) Runtime Data Area

這是 JVM 里最重要的部分,也是面試追問的重災(zāi)區(qū)。

1. 程序計數(shù)器(Program Counter Register)

特點:

  • 很小,只存一個指針
  • 指向下一條要執(zhí)行的字節(jié)碼指令
  • 線程私有:每個線程都有自己的 PC

為什么不會 OOM?

因為它只存一個指令地址,大小固定,不會動態(tài)增長。

唯一沒有 GC 的區(qū)域。

2. 虛擬機棧(VM Stack)

特點:

  • 線程私有
  • 存儲方法調(diào)用的數(shù)據(jù)
  • 每個方法叫一個棧幀(Stack Frame)

一個棧幀包含:

  • 局部變量表(方法參數(shù) + 局部變量)
  • 操作數(shù)棧(計算時的臨時空間)
  • 動態(tài)鏈接(指向常量池的引用)
  • 返回地址

會 OOM 嗎?

會。如果遞歸沒寫好,棧深度超過限制,就會 StackOverflowError。

我之前寫遞歸算法就踩過這個坑:

// 死遞歸,棧溢出
public int sum(int n) {
    return sum(n) + 1;  // 沒有終止條件
}

3. 本地方法棧(Native Method Stack)

和虛擬機棧一樣,只不過服務(wù)的是本地方法(native keyword 修飾的方法)。

JNI 調(diào)用(C/C++ 寫的代碼)會用到這里。

4. 堆(Heap)

JVM 里最大的內(nèi)存區(qū)域。

  • 存儲對象實例和數(shù)組
  • 線程共享:所有線程都能訪問
  • GC 的主要戰(zhàn)場

為什么要分代?

因為對象的生命周期不同:

  • 新生代:剛創(chuàng)建的對象(朝生夕死)
  • 老年代:存活時間長的對象
  • 分代后,GC 更有針對性,效率更高

5. 方法區(qū)(Method Area)

存儲:

  • 類的元信息(類名、修飾符、父類)
  • 類的結(jié)構(gòu)(字段、方法)
  • 運行時常量池(字面量和符號引用)
  • JIT 編譯后的代碼緩存

JDK 1.8 的變化:

之前方法區(qū)在堆里,叫 Permanent Generation(永久代)。

JDK 1.8 改成了 Metaspace,放在本地內(nèi)存里。

版本方法區(qū)實現(xiàn)位置
JDK 1.7PermGen堆內(nèi)
JDK 1.8Metaspace本地內(nèi)存

為什么要改?

因為 PermGen 容易 OOM。你要是項目中依賴了一堆 jar 包,PermGen 分分鐘爆掉。

四、執(zhí)行引擎 Execution Engine

它干什么的?

把字節(jié)碼翻譯成機器碼,讓 CPU 執(zhí)行。

解釋器 vs JIT 編譯器

組件特點適用場景
解釋器逐行翻譯,立即執(zhí)行啟動階段,一次性執(zhí)行
JIT 編譯器編譯成機器碼,緩存起來熱點代碼,多次執(zhí)行

JIT 的熱點探測:

JVM 會監(jiān)控方法的執(zhí)行頻率,熱點代碼會被 JIT 編譯成機器碼。

兩個計數(shù)器:

  • 方法調(diào)用計數(shù)器
  • 回邊計數(shù)器(循環(huán)體)

超過閾值就觸發(fā)編譯。

垃圾回收器

GC 是 JVM 里最復(fù)雜也最常問的部分。

常見 GC 算法:

算法原理缺點
標記-清除標記存活對象,清理未標記的產(chǎn)生內(nèi)存碎片
復(fù)制把活對象復(fù)制到另一半空間浪費一半內(nèi)存
標記-整理標記后整理內(nèi)存整理耗時

常見垃圾回收器:

  • Serial(單線程)
  • Parallel(多線程,吞吐量優(yōu)先)
  • CMS(并發(fā)標記清除,低停頓)
  • G1(REGION劃分,可預(yù)測停頓)
  • ZGC / Shenandoah(超低停頓,JDK 11+)

五、本地接口 JNI

Java 不是萬能的,有些場景需要調(diào)用本地代碼(C/C++)。

JNI 就是 Java 和 native 代碼之間的橋梁。

典型場景:

  • 調(diào)用操作系統(tǒng) API
  • 追求極致性能(數(shù)學(xué)計算)
  • 訪問硬件
public native String hello();  // native 方法,調(diào)用 C 實現(xiàn)

六、記憶口訣

JVM 三大部分:
┌─────────────────────────────────┐
│  類加載器 ──── 加載字節(jié)碼 ? ? ? │
│  運行時數(shù)據(jù)區(qū) ── 分配內(nèi)存 ? ? ? │
│  執(zhí)行引擎 ──── 執(zhí)行字節(jié)碼 ? ? ? │
└─────────────────────────────────┘
運行時數(shù)據(jù)區(qū)五塊:
計數(shù)器(無GC)
虛擬機棧(存方法調(diào)用,會OOM)
本地方法棧(native方法)
堆(對象,會GC)
方法區(qū)(類信息)
雙親委派:
Bootstrap → Extension → Application

寫在最后

JVM 這塊知識,面試基本必問。

我踩過的坑是:只背概念,不畫圖。

后來我把 JVM 的結(jié)構(gòu)畫了 5 遍,把每個區(qū)域的作用、特點、常見問題都寫上,面試時直接畫給面試官看。

面試官當(dāng)時眼睛一亮,說:"這個理解方式不錯。"

技術(shù)表達很重要。能畫出來、講清楚,比背出來強 100 倍。

到此這篇關(guān)于JVM 有哪些組成部分:面試必問的 Java 運行時架構(gòu)的文章就介紹到這了,更多相關(guān)java運行時架構(gòu)jvm內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java安全 ysoserial CommonsCollections3示例分析

    Java安全 ysoserial CommonsCollections3示例分析

    這篇文章主要為大家介紹了Java安全 ysoserial CommonsCollections3示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-10-10
  • java中map與實體類的相互轉(zhuǎn)換操作

    java中map與實體類的相互轉(zhuǎn)換操作

    這篇文章主要介紹了java中map與實體類的相互轉(zhuǎn)換操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java通過Caffeine和自定義注解實現(xiàn)本地防抖接口限流

    Java通過Caffeine和自定義注解實現(xiàn)本地防抖接口限流

    Caffeine?是目前Java領(lǐng)域最熱門,性能最高的本地內(nèi)存緩存庫,本文為大家詳細介紹了如何利用Caffeine和自定義注解實現(xiàn)本地防抖接口限流功能,需要的可以了解下
    2025-05-05
  • MyBatis處理懶加載和預(yù)加載的實戰(zhàn)詳解

    MyBatis處理懶加載和預(yù)加載的實戰(zhàn)詳解

    在Java開發(fā)中,MyBatis是一個廣泛使用的持久層框架,它為開發(fā)者提供了靈活、強大的數(shù)據(jù)訪問能力,兩種常用的加載策略是懶加載和預(yù)加載,本文將介紹這兩種加載方式的概念、適用場景以及MyBatis中的實現(xiàn)方式,需要的朋友可以參考下
    2026-02-02
  • 深入理解java動態(tài)代理的兩種實現(xiàn)方式(JDK/Cglib)

    深入理解java動態(tài)代理的兩種實現(xiàn)方式(JDK/Cglib)

    本篇文章主要介紹了java動態(tài)代理的兩種實現(xiàn)方式,詳細的介紹了JDK和Cglib的實現(xiàn)方法,具有一定的參考價值,有興趣的可以了解一下
    2017-04-04
  • java字符串日期類Date和Calendar相互轉(zhuǎn)化及相關(guān)常用方法

    java字符串日期類Date和Calendar相互轉(zhuǎn)化及相關(guān)常用方法

    Java語言的Calendar(日歷),Date(日期),和DateFormat(日期格式)組成了Java標準的一個基本但是非常重要的部分,下面這篇文章主要給大家介紹了關(guān)于java字符串日期類Date和Calendar相互轉(zhuǎn)化及相關(guān)常用方法的相關(guān)資料,需要的朋友可以參考下
    2023-12-12
  • 匯總Java中List 去重的 6 種方法

    匯總Java中List 去重的 6 種方法

    這篇文章主要介紹了匯總Java中List 去重的 6 種方法,文章圍繞主題展開List去重的方法,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-05-05
  • 解讀@ResponseBody與@RequestBody注解的用法

    解讀@ResponseBody與@RequestBody注解的用法

    這篇文章主要介紹了Spring MVC中的@ResponseBody和@RequestBody注解的用法,@ResponseBody注解用于將Controller方法的返回對象轉(zhuǎn)換為指定格式(如JSON)并通過Response響應(yīng)給客戶端,@RequestBody注解用于讀取HTTP請求的內(nèi)容
    2024-11-11
  • java springmvc實現(xiàn)驗證碼功能

    java springmvc實現(xiàn)驗證碼功能

    這篇文章主要為大家詳細介紹了java springmvc實現(xiàn)驗證碼功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • IDEA中實體類(POJO)與JSON快速互轉(zhuǎn)問題

    IDEA中實體類(POJO)與JSON快速互轉(zhuǎn)問題

    這篇文章主要介紹了IDEA中實體類(POJO)與JSON快速互轉(zhuǎn),本文通過圖文實例代碼相結(jié)合給大家介紹的非常詳細,需要的朋友可以參考下
    2022-08-08

最新評論

衡水市| 搜索| 沿河| 桦川县| 历史| 达州市| 奉化市| 阳曲县| 靖安县| 寿宁县| 定西市| 唐河县| 柞水县| 进贤县| 玛纳斯县| 亚东县| 德安县| 察隅县| 博野县| 湘潭市| 理塘县| 顺义区| 抚顺市| 梨树县| 海宁市| 常德市| 海南省| 克拉玛依市| 临漳县| 蓬莱市| 沂水县| 措勤县| 青神县| 彰化市| 阿拉善左旗| 牡丹江市| 福清市| 澄迈县| 肥城市| 于都县| 无为县|