掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
大家好,今天總結(jié)了一下老生常談的 JVM,這也是面試必問的知識(shí)。

創(chuàng)新互聯(lián)建站為企業(yè)級(jí)客戶提高一站式互聯(lián)網(wǎng)+設(shè)計(jì)服務(wù),主要包括網(wǎng)站制作、成都做網(wǎng)站、app軟件開發(fā)公司、微信小程序定制開發(fā)、宣傳片制作、LOGO設(shè)計(jì)等,幫助客戶快速提升營銷能力和企業(yè)形象,創(chuàng)新互聯(lián)各部門都有經(jīng)驗(yàn)豐富的經(jīng)驗(yàn),可以確保每一個(gè)作品的質(zhì)量和創(chuàng)作周期,同時(shí)每年都有很多新員工加入,為我們帶來大量新的創(chuàng)意。
話不多說,整起來!
一、JVM 是什么?
1、Java 虛擬機(jī)(Jvm)是可運(yùn)行 Java 代碼的假想計(jì)算機(jī)。
2、Jvm 充當(dāng)著一個(gè)翻譯官的角色,我們平常所編寫出的 Java 程序,是不能夠被操作系統(tǒng)所直接識(shí)別的,這時(shí)候 JVM 的作用就體現(xiàn)出來了,它負(fù)責(zé)把我們的程序翻譯給系統(tǒng)“聽”,告訴它我們的程序需要做什么操作。
3、Jvm 針對(duì)每個(gè)操作系統(tǒng)開發(fā)其對(duì)應(yīng)的解釋器,所以只要其操作系統(tǒng)有對(duì)應(yīng)版本的 Jvm,那么這份 Java 編譯后的代碼就能夠運(yùn)行起來,有句話大家一定聽說過:「Java 能一次編譯到處運(yùn)行」,這就是原因所在。
二、Jvm 的體系架構(gòu)?
Jvm 是這四部分組成:
下面就聊聊這四個(gè)部分~~
2.1 運(yùn)行區(qū)數(shù)據(jù)
Java 虛擬機(jī)在執(zhí)行 Java 程序的過程中會(huì)把它所管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域,這些區(qū)域各有各的作用,各有各的生命周期。
有些區(qū)域隨著虛擬機(jī)進(jìn)程的啟動(dòng)而存在,有些區(qū)域則依賴用戶線程的啟動(dòng)和結(jié)束建立和銷毀。
運(yùn)行區(qū)數(shù)據(jù)的劃分:方法區(qū)、虛擬機(jī)棧,本地方法棧、堆、程序計(jì)數(shù)器
上面這張圖大家一定都見過,其實(shí)可以劃分的更細(xì)點(diǎn),看下面的這兩張圖:
能看出 1.8 版本前后的差別么,下面就看看這些區(qū)域都干啥的~~
程序計(jì)數(shù)器
特點(diǎn):1、占用很小的內(nèi)存 2、各線程私有
就比如下面字節(jié)碼一樣,每一行開頭的黃色數(shù)字,我們就可以認(rèn)為它是程序計(jì)數(shù)器所存儲(chǔ)的內(nèi)容:
- public void doSth1();
- descriptor: ()V
- flags: ACC_PUBLIC
- Code:
- stack=2, locals=3, args_size=1
- 0: ldc #5
- 2: dup
- 3: astore_1
- 4: monitorenter
- 5: getstatic #2
- 8: ldc #3
- 10: invokevirtual #4
- 13: aload_1
虛擬機(jī)棧
特點(diǎn):1、隨線程而生、隨線程而死 2、先進(jìn)后出
棧示意圖:
本地方法棧
特點(diǎn):1、各線程私有 2、和本地方法有關(guān)
native 修飾的方法:
- public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
堆
特點(diǎn):1、所有線程共享 2、占用大的內(nèi)存空間 3、先進(jìn)先出
堆的劃分:
方法區(qū)
特點(diǎn):1、所有線程共享 2、1.8 之后移到了元空間 3、涉及到常量池
直接內(nèi)存
從上面的圖中,看到有直接內(nèi)存這個(gè)區(qū)域
2.2 類加載器
1、什么是類加載機(jī)制?
JVM 運(yùn)行時(shí),java 虛擬機(jī)會(huì)把描述類的數(shù)據(jù)從 Class 文件加載到內(nèi)存,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)、轉(zhuǎn)換、解析和初始化,最終形成可以被 jvm 可以直接使用的類型,這就是類加載機(jī)制。
2、說說類加載的過程?
開局一張圖:
這張圖說明了類從加載到虛擬機(jī)內(nèi)存開始,到卸載出內(nèi)存為止,它的整個(gè)生命周期。
一般來說,我們把 Java 的類加載過程分為三個(gè)主要步驟:加載、鏈接、初始化,具體行為在 Java 虛擬機(jī)規(guī)范里有非常詳細(xì)的定義。
1、首先是加載階段
2、第二階段是鏈接,這是核心的步驟,簡單說是把原始的類定義信息平滑地轉(zhuǎn)化入 JVM 運(yùn)行的過程中。這里可進(jìn)一步細(xì)分為三個(gè)步驟:
① 驗(yàn)證
② 準(zhǔn)備
這里的初始化是指:
1、8 種基本數(shù)據(jù)類型的默認(rèn)初始值是 0。
2、引用類型默認(rèn)的初始值是 null。
3、對(duì)于有 static final 修飾的常量會(huì)直接賦值,例如:static final int x=123;則 x 直接會(huì)初始化為 123。
③ 解析
3、最后是初始化階段
這一步真正去執(zhí)行類初始化的代碼邏輯,包括靜態(tài)字段動(dòng)作,以及執(zhí)行類定定義中的靜態(tài)初始化塊內(nèi)的邏輯編譯器在編譯階段就會(huì)把這部分邏輯整理好,父類型的初始化邏輯優(yōu)先于當(dāng)前類型的邏輯。
初始化順序:
三、什么時(shí)候會(huì)對(duì)類進(jìn)行初始化?
通過 new 關(guān)鍵字實(shí)例化對(duì)象、讀取或設(shè)置類的靜態(tài)變量、調(diào)用類的靜態(tài)方法
通過反射發(fā)生上面的三種行為
初始化子類時(shí),會(huì)觸發(fā)父類的初始化
作為程序入口運(yùn)行,就是指的 main 方法
四、類加載器有哪些?
啟動(dòng)類加載器:負(fù)責(zé)加載環(huán)境變量下 jre/lib 下面的 jar 文件
擴(kuò)展類加載器:負(fù)責(zé)加載環(huán)境變量下 jre/lib/ext 目錄下面的 jar 包
應(yīng)用類加載器:就是加載我們熟悉的 classpath 的內(nèi)容
自定義加載器:繼承 ClassLoader 就可以實(shí)現(xiàn)
五、了解雙親委派模型嗎?
這是一張很經(jīng)典的圖,通常情況下,各個(gè)類加載器的協(xié)作關(guān)系就是這樣的。
概念:就是說一個(gè)類加載器收到了類加載的請(qǐng)求,不會(huì)自己先加載,而是把它交給自己的父類去加載,層層迭代。
用上圖來說明就是如果應(yīng)用程序類加載器收到了一個(gè)類加載的請(qǐng)求,會(huì)先給擴(kuò)展類加載器,然后再給啟動(dòng)類加載器,如果啟動(dòng)類加載器無法完成這個(gè)類加載的請(qǐng)求,再返回給擴(kuò)展類加載器,如果擴(kuò)展類加載器也無法完成,最后才會(huì)到應(yīng)用類加載器。
好處:1、避免重復(fù)加載 Java 類型 2、沙箱安全機(jī)制:保證核心的類不會(huì)被篡改。
六、classLoader與class.forName區(qū)別
七、腦圖
最后送大家一張自己總結(jié)的腦圖呀
今天就寫到這里啦!!
給大家介紹了JVM、運(yùn)行區(qū)數(shù)據(jù)、類加載機(jī)制。希望大家面試前能掌握和Jvm有關(guān)的知識(shí)。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流