亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

jvm運(yùn)行原理以及類(lèi)加載器實(shí)例詳解

 更新時(shí)間:2021年05月02日 10:50:41   作者:silly8543  
這篇文章主要給大家介紹了關(guān)于jvm運(yùn)行原理以及類(lèi)加載器的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

JVM運(yùn)行原理

首先從“.java”代碼文件,編譯成“.class”字節(jié)碼文件,然后類(lèi)加載器將“.class”字節(jié)碼文件中的類(lèi)給加載帶JVM中,最后就是JVM執(zhí)行寫(xiě)好的代碼。執(zhí)行過(guò)程如下圖

類(lèi)加載器

類(lèi)加載過(guò)程

加載 -> 驗(yàn)證 -> 準(zhǔn)備 -> 解析 -> 初始化 -> 使用 -> 卸載

加載

一旦JVM進(jìn)程啟動(dòng)之后,一定會(huì)先把類(lèi)加載到內(nèi)存中,然后從main()方法的入口代碼開(kāi)始執(zhí)行

public class HelloWorld {
    public static void main(String[] args) {
        
    }
}

加載指是將類(lèi)CLass文件讀入到內(nèi)存中,并創(chuàng)建一個(gè)java.lang.Class對(duì)象

類(lèi)的加載器由類(lèi)加載器完成,類(lèi)加載器通常由JVM提供,除此之外,可以通過(guò)繼承ClassLoader基類(lèi)來(lái)創(chuàng)建自己的類(lèi)加載器

通過(guò)使用不同的類(lèi)加載器,可以從不同來(lái)源加載類(lèi)的二進(jìn)制數(shù)據(jù)

  • 從本地文件系統(tǒng)加載class文件
  • 從JAR包加載class文件,JDBC編程時(shí)用到的數(shù)據(jù)庫(kù)驅(qū)動(dòng)類(lèi)就放在JAR文件中,JVM可以從JAR文件中直接加載該class文件
  • 通過(guò)網(wǎng)絡(luò)加載class文件
  • 把一個(gè)java源文件動(dòng)態(tài)編譯,并執(zhí)行加載

準(zhǔn)備階段

驗(yàn)證

根據(jù)Java虛擬機(jī)規(guī)范,來(lái)校驗(yàn)加載進(jìn)來(lái)的“.class”文件中的內(nèi)容,是否符合指定的規(guī)范,如果“.class”文件被人篡改,里面的字節(jié)碼不符合規(guī)范,那么JVM是沒(méi)法執(zhí)行這個(gè)字節(jié)碼。所在把“.class”文件加載到內(nèi)存后,必須先驗(yàn)證一下,檢驗(yàn)他必須完全符合JVM規(guī)范,才交給JVM來(lái)運(yùn)行。其主要包括四種驗(yàn)證,文件格式驗(yàn)證,元數(shù)據(jù)驗(yàn)證,字節(jié)碼驗(yàn)證,符號(hào)引用驗(yàn)證

  • 文件格式驗(yàn)證:主要驗(yàn)證字節(jié)流是否符合Class文件格式規(guī)范,并且能被當(dāng)前的虛擬機(jī)加載處理。例如:主,次版本號(hào)是否在當(dāng)前虛擬機(jī)處理的范圍之內(nèi)。常量池中是否有不被支持的常量類(lèi)型。指向常量的中的索引值是否存在不存在的常量或不符合類(lèi)型的常量
  • 元數(shù)據(jù)驗(yàn)證:對(duì)字節(jié)碼描述的信息進(jìn)行語(yǔ)義的分析,分析是否符合java的語(yǔ)言語(yǔ)法的規(guī)范
  • 字節(jié)碼驗(yàn)證:最重要的驗(yàn)證環(huán)節(jié),分析數(shù)據(jù)流和控制,確定語(yǔ)義是合法的,符合邏輯的。主要的針對(duì)元數(shù)據(jù)驗(yàn)證后對(duì)方法體的驗(yàn)證。保證類(lèi)方法在運(yùn)行時(shí)不會(huì)有危害出現(xiàn)
  • 符號(hào)引用驗(yàn)證:主要是針對(duì)符號(hào)引用轉(zhuǎn)換為直接引用的時(shí)候,是會(huì)延伸到第三解析階段,主要去確定訪問(wèn)類(lèi)型等涉及到引用的情況,主要是要保證引用一定會(huì)被訪問(wèn)到,不會(huì)出現(xiàn)類(lèi)等無(wú)法訪問(wèn)的問(wèn)題

準(zhǔn)備

給引用的類(lèi)分配一定的內(nèi)存空間,然后給里面的類(lèi)變量(也就是static修飾的變量)分配內(nèi)存空間,來(lái)一個(gè)默認(rèn)的初始值

解析

實(shí)際上是把將類(lèi)的二進(jìn)制數(shù)據(jù)中的符號(hào)引用替換成直接引用的過(guò)程,這個(gè)部分的內(nèi)容比較復(fù)雜,設(shè)計(jì)到JVM的底層

  • 符號(hào)引用:符號(hào)引用是以一組符號(hào)來(lái)描述所引用的目標(biāo),符號(hào)可以是任何的字面形式的字面量,只要不會(huì)出現(xiàn)沖突能夠定位到就行。布局和內(nèi)存無(wú)關(guān)
  • 直接引用:是指向目標(biāo)的指針,偏移量或者能夠直接定位的句柄。該引用是和內(nèi)存中的布局有關(guān)的,并且一定加載進(jìn)來(lái)的

解析主要包括:

  • 類(lèi)或接口的解析
  • 字段解析
  • 類(lèi)方法解析
  • 接口方法解析

初始化

初始化是為類(lèi)的靜態(tài)變量賦予正確的初始值,準(zhǔn)備階段和初始化階段看似有點(diǎn)矛盾,其實(shí)是不矛盾的,如果類(lèi)中有語(yǔ)句:private static int a = 10,它的執(zhí)行過(guò)程是這樣的,首先字節(jié)碼文件被加載到內(nèi)存后,先進(jìn)行鏈接的驗(yàn)證這一步驟,驗(yàn)證通過(guò)后準(zhǔn)備階段,給a分配內(nèi)存,因?yàn)樽兞縜是static的,所以此時(shí)a等于int類(lèi)型的默認(rèn)初始值0,即a=0,然后到解析(后面在說(shuō)),到初始化這一步驟時(shí),才把a(bǔ)的真正的值10賦給a,此時(shí)a=10

一個(gè)非常重要的規(guī)則,就是如果初始化一個(gè)類(lèi)的時(shí)候,發(fā)現(xiàn)他的父類(lèi)還沒(méi)初始化,那么必須先初始化他的父類(lèi)

加載器

啟動(dòng)類(lèi)/根類(lèi)加載器

Bootstrap ClassLoader,他主要是負(fù)責(zé)加載我們?cè)跈C(jī)器上安裝的Java目錄下的核心類(lèi)的,是用原生代碼來(lái)實(shí)現(xiàn)的,并不繼承自 java.lang.ClassLoader(負(fù)責(zé)加載$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++實(shí)現(xiàn),不是ClassLoader子類(lèi))。由于引導(dǎo)類(lèi)加載器涉及到虛擬機(jī)本地實(shí)現(xiàn)細(xì)節(jié),開(kāi)發(fā)者無(wú)法直接獲取到啟動(dòng)類(lèi)加載器的引用,所以不允許直接通過(guò)引用進(jìn)行操作

擴(kuò)展類(lèi)加載器

Extension ClassLoader,負(fù)責(zé)加載JRE的擴(kuò)展目錄,lib/ext或者由java.ext.dirs系統(tǒng)屬性指定的目錄中的JAR包的類(lèi)。由Java語(yǔ)言實(shí)現(xiàn),父類(lèi)加載器為null

應(yīng)用程序類(lèi)加載器

Application ClassLoader,被稱(chēng)為應(yīng)用(也稱(chēng)為系統(tǒng))類(lèi)加載器,它負(fù)責(zé)在JVM啟動(dòng)時(shí)加載來(lái)自Java命令的-classpath選項(xiàng)、java.class.path系統(tǒng)屬性,或者CLASSPATH換將變量所指定的JAR包和類(lèi)路徑。程序可以通過(guò)ClassLoader的靜態(tài)方法getSystemClassLoader()來(lái)獲取系統(tǒng)類(lèi)加載器。如果沒(méi)有特別指定,則用戶(hù)自定義的類(lèi)加載器都以此類(lèi)加載器作為父加載器。由Java語(yǔ)言實(shí)現(xiàn),父類(lèi)加載器為ExtClassLoader。

類(lèi)加載器加載Class大致要經(jīng)過(guò)如下8個(gè)步驟:

  1. 檢測(cè)此Class是否載入過(guò),即在緩沖區(qū)中是否有此Class,如果有直接進(jìn)入第8步,否則進(jìn)入第2步
  2. 如果沒(méi)有父類(lèi)加載器,則要么Parent是根類(lèi)加載器,要么本身就是根類(lèi)加載器,則跳到第4步,如果父類(lèi)加載器存在,則進(jìn)入第3步
  3. 請(qǐng)求使用父類(lèi)加載器去載入目標(biāo)類(lèi),如果載入成功則跳至第8步,否則接著執(zhí)行第5步
  4. 請(qǐng)求使用根類(lèi)加載器去載入目標(biāo)類(lèi),如果載入成功則跳至第8步,否則跳至第7步
  5. 當(dāng)前類(lèi)加載器嘗試尋找Class文件,如果找到則執(zhí)行第6步,如果找不到則執(zhí)行第7步
  6. 從文件中載入Class,成功后跳至第8步
  7. 拋出ClassNotFountException異常
  8. 返回對(duì)應(yīng)的java.lang.Class對(duì)象

自定義類(lèi)加載器

除了上面那幾種之外,還可以自定義類(lèi)加載器,去根據(jù)你自己的需求加載你的類(lèi)

類(lèi)加載機(jī)制

JVM的類(lèi)加載機(jī)制主要有如下3種:

  • 全盤(pán)負(fù)責(zé):所謂全盤(pán)負(fù)責(zé),就是當(dāng)一個(gè)類(lèi)加載器負(fù)責(zé)加載某個(gè)Class時(shí),該Class所依賴(lài)和引用其他Class也將由該類(lèi)加載器負(fù)責(zé)載入,除非顯示使用另外一個(gè)類(lèi)加載器來(lái)載入
  • 雙親委派:所謂的雙親委派,則是先讓父類(lèi)加載器試圖加載該Class,只有在父類(lèi)加載器無(wú)法加載該類(lèi)時(shí)才嘗試從自己的類(lèi)路徑中加載該類(lèi)。通俗的講,就是某個(gè)特定的類(lèi)加載器在接到加載類(lèi)的請(qǐng)求時(shí),首先將加載任務(wù)委托給父加載器,依次遞歸,如果父加載器可以完成類(lèi)加載任務(wù),就成功返回;只有父加載器無(wú)法完成此加載任務(wù)時(shí),才自己去加載
  • 緩存機(jī)制。緩存機(jī)制將會(huì)保證所有加載過(guò)的Class都會(huì)被緩存,當(dāng)程序中需要使用某個(gè)Class時(shí),類(lèi)加載器先從緩存區(qū)中搜尋該Class,只有當(dāng)緩存區(qū)中不存在該Class對(duì)象時(shí),系統(tǒng)才會(huì)讀取該類(lèi)對(duì)應(yīng)的二進(jìn)制數(shù)據(jù),并將其轉(zhuǎn)換成Class對(duì)象,存入緩沖區(qū)中。這就是為很么修改了Class后,必須重新啟動(dòng)JVM,程序所做的修改才會(huì)生效的原因

雙親委派機(jī)制

這就是所謂的**雙親委派模型:**先找父親去加載,不行的話(huà)再由兒子來(lái)加載

  • 雙親委派機(jī)制,其工作原理的是,如果一個(gè)類(lèi)加載器收到了類(lèi)加載請(qǐng)求,它并不會(huì)自己先去加載,而是把這個(gè)請(qǐng)求委托給父類(lèi)的加載器去執(zhí)行,如果父類(lèi)加載器還存在其父類(lèi)加載器,則進(jìn)一步向上委托,依次遞歸,請(qǐng)求最終將到達(dá)頂層的啟動(dòng)類(lèi)加載器,如果父類(lèi)加載器可以完成類(lèi)加載任務(wù),就成功返回,倘若父類(lèi)加載器無(wú)法完成此加載任務(wù),子加載器才會(huì)嘗試自己去加載,這就是雙親委派模式,即每個(gè)兒子都很懶,每次有活就丟給父親去干,直到父親說(shuō)這件事我也干不了時(shí),兒子自己才想辦法去完成
  • 雙親委派機(jī)制的優(yōu)勢(shì):采用雙親委派模式的是好處是Java類(lèi)隨著它的類(lèi)加載器一起具備了一種帶有優(yōu)先級(jí)的層次關(guān)系,通過(guò)這種層級(jí)關(guān)可以避免類(lèi)的重復(fù)加載,當(dāng)父親已經(jīng)加載了該類(lèi)時(shí),就沒(méi)有必要子ClassLoader再加載一次。其次是考慮到安全因素,java核心api中定義類(lèi)型不會(huì)被隨意替換,假設(shè)通過(guò)網(wǎng)絡(luò)傳遞一個(gè)名為java.lang.Integer的類(lèi),通過(guò)雙親委托模式傳遞到啟動(dòng)類(lèi)加載器,而啟動(dòng)類(lèi)加載器在核心Java API發(fā)現(xiàn)這個(gè)名字的類(lèi),發(fā)現(xiàn)該類(lèi)已被加載,并不會(huì)重新加載網(wǎng)絡(luò)傳遞的過(guò)來(lái)的java.lang.Integer,而直接返回已加載過(guò)的Integer.class,這樣便可以防止核心API庫(kù)被隨意篡改

總結(jié)

到此這篇關(guān)于jvm運(yùn)行原理以及類(lèi)加載器的文章就介紹到這了,更多相關(guān)jvm運(yùn)行原理及類(lèi)加載器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中引用類(lèi)型class的用法總結(jié)

    Java中引用類(lèi)型class的用法總結(jié)

    這篇文章主要為大家詳細(xì)介紹了Java中引用類(lèi)型class的用法的相關(guān)資料,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定幫助,感興趣的可以了解一下
    2022-10-10
  • 詳解Spring?Security怎么從數(shù)據(jù)庫(kù)加載我們的用戶(hù)

    詳解Spring?Security怎么從數(shù)據(jù)庫(kù)加載我們的用戶(hù)

    這篇文章主要為大家介紹了Spring?Security怎么從數(shù)據(jù)庫(kù)加載我們的用戶(hù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Maven deploy plugin使用方式

    Maven deploy plugin使用方式

    這篇文章主要介紹了Maven deploy plugin使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • java中對(duì)HashMap的put過(guò)程解讀

    java中對(duì)HashMap的put過(guò)程解讀

    這篇文章主要介紹了java中對(duì)HashMap的put過(guò)程解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Spring基礎(chǔ)之AOP的概念介紹

    Spring基礎(chǔ)之AOP的概念介紹

    AOP是Spring的關(guān)鍵特性之一,雖然Spring的IOC特性并不依賴(lài)于AOP,本文重點(diǎn)介紹AOP編程中的一些術(shù)語(yǔ),這些術(shù)語(yǔ)不僅僅局限于Spring,它適用于所有的AOP編程,感興趣的朋友一起看看吧
    2022-06-06
  • Mybatis的Cursor避免OOM異常的方法詳解

    Mybatis的Cursor避免OOM異常的方法詳解

    在Mybatis中,有一個(gè)特殊的對(duì)象Cursor,這個(gè)對(duì)象的注釋上清晰的說(shuō)明了,這個(gè)類(lèi)的用途,在Mybatis中使用Cursor非常簡(jiǎn)單,只要在Mapper文件中將方法的返回值設(shè)置成Cursor<T>即可,本文給大家介紹了Mybatis的Cursor避免OOM異常的方法,需要的朋友可以參考下
    2024-06-06
  • 淺析Java中對(duì)稱(chēng)與非對(duì)稱(chēng)加密算法原理與使用

    淺析Java中對(duì)稱(chēng)與非對(duì)稱(chēng)加密算法原理與使用

    密碼學(xué)是研究編制密碼和破譯密碼的技術(shù)科學(xué)。這篇文章主要為大家介紹了Java中對(duì)稱(chēng)與非對(duì)稱(chēng)加密算法的原理與使用,感興趣的小伙伴可以了解一下
    2023-03-03
  • CorsFilter 過(guò)濾器解決跨域的處理

    CorsFilter 過(guò)濾器解決跨域的處理

    這篇文章主要介紹了CorsFilter 過(guò)濾器解決跨域的處理操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Springboot如何切換默認(rèn)的Tomcat容器

    Springboot如何切換默認(rèn)的Tomcat容器

    這篇文章主要介紹了Springboot如何切換默認(rèn)的Tomcat容器,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Java CAS機(jī)制的一些理解

    Java CAS機(jī)制的一些理解

    這篇文章主要介紹了Java CAS機(jī)制的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-05-05

最新評(píng)論