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

通俗講解JVM的類加載機(jī)制

 更新時(shí)間:2020年09月28日 10:52:44   作者:H.U.C-王子  
這篇文章主要介紹了JVM的類加載機(jī)制的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java,感興趣的朋友可以了解下

前言

我們很多小伙伴平時(shí)都是做JAVA開(kāi)發(fā)的,那么作為一名合格的工程師,你是否有仔細(xì)的思考過(guò)JVM的運(yùn)行原理呢。

如果懂得了JVM的運(yùn)行原理和內(nèi)存模型,像是一些JVM調(diào)優(yōu)、垃圾回收機(jī)制等等的問(wèn)題我們才能有一個(gè)更清晰的概念。

為了走進(jìn)JVM,深入了解底層,王子打算寫一個(gè)JVM的專題,留下自己對(duì)JVM探索的足跡,同時(shí)也希望能幫到小伙伴們更好的理解JVM。

那我們開(kāi)始吧。

JAVA代碼的運(yùn)行流程

首先我們就來(lái)聊一聊JAVA代碼是怎么運(yùn)行起來(lái)的,這部分比較基礎(chǔ)相信大家都知道,就當(dāng)成是個(gè)復(fù)習(xí)吧。

我們編寫的代碼都是在java文件中編寫的,然后會(huì)編譯成class字節(jié)碼文件。

當(dāng)我們使用到哪個(gè)類的時(shí)候就會(huì)通過(guò)類加載器把class字節(jié)碼文件中的類加載到j(luò)vm內(nèi)存中,然后就是在jvm內(nèi)存中運(yùn)行我們的代碼了。

整體的運(yùn)行流程就是這樣,相信小伙伴們都很清楚這些,但是有關(guān)類加載器是如何把類加載到j(luò)vm內(nèi)存中的,小伙伴們有考慮過(guò)嗎?

今天我們主要就是聊這一部分。

JVM什么時(shí)候加載類

其實(shí)說(shuō)到類加載的底層機(jī)制,這是一個(gè)很復(fù)雜的過(guò)程,但是對(duì)于我們平時(shí)的工作來(lái)講,只要懂得它的核心原理就可以了。

一個(gè)類的加載過(guò)程會(huì)經(jīng)歷如下的幾個(gè)過(guò)程:

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

首先我們就先弄明白一個(gè)問(wèn)題,jvm是什么時(shí)候去加載類的呢?

其實(shí)答案很簡(jiǎn)單,就是我們什么時(shí)候使用到了這個(gè)類,它就去class字節(jié)碼文件中去加載這個(gè)類。

而作為程序的入口,具有main方法的類,肯定是最開(kāi)始的時(shí)候就加載到j(luò)vm中了。

對(duì)于加載類的時(shí)間點(diǎn)問(wèn)題,其實(shí)就是這么簡(jiǎn)單。

類加載器和雙親委派機(jī)制

既然我們知道了類加載的時(shí)間點(diǎn),那么jvm是通過(guò)什么方式對(duì)類進(jìn)行加載的呢?就是類加載器。

那接下來(lái)我們就來(lái)聊聊jvm的類加載器。

jvm的類加載器總體上可以分成4層,我們一起看一下。

1.啟動(dòng)類加載器

首先就是jvm啟動(dòng)的第一道關(guān)口,啟動(dòng)類加載器Bootstrap ClassLoader,它主要是加載java的核心類。

相信大家都知道,無(wú)論是什么環(huán)節(jié)下運(yùn)行java程序,都是要安裝jvm虛擬機(jī)環(huán)境的,而在這個(gè)環(huán)境的目錄中是有一個(gè)lib文件夾的,這個(gè)文件下就是java最核心的類庫(kù),支撐著java系統(tǒng)的運(yùn)行。

所以一旦jvm啟動(dòng),那么首先就會(huì)通過(guò)啟動(dòng)類加載器去加載lib文件夾下的核心類庫(kù)。

2.擴(kuò)展類加載器

然后我們就到了第二層,擴(kuò)展類加載器Extension ClassLoader,這個(gè)類加載器其實(shí)與啟動(dòng)類加載器是類似的。

在我們的jvm虛擬機(jī)環(huán)境目錄下,是有一個(gè)lib/ext的文件夾的,這里面的類就是java運(yùn)行環(huán)境的一些擴(kuò)展類,這些擴(kuò)展類就是在jvm啟動(dòng)后,通過(guò)擴(kuò)展類加載器進(jìn)行加載的。

3.應(yīng)用程序類加載器

加載完核心類庫(kù)和擴(kuò)展類,這時(shí)候就到了第三層,應(yīng)用程序類加載器Application ClassLoader,這個(gè)類加載器你就可以理解成是加載我們寫好的java代碼的就可以了。

4.自定義類加載器

前面的三層就是基本的類加載器了,然后第四層是自定義類加載器,根據(jù)一些特殊的需求來(lái)自己定義類加載器加載我們的類。

整體上類加載器就是這么的4層結(jié)構(gòu)。很多小伙伴可能都聽(tīng)說(shuō)過(guò)雙親委派機(jī)制,那么什么是雙親委派機(jī)制呢,王子就和大家用最接地氣的語(yǔ)言描述一下。

其實(shí)很好理解,就是當(dāng)我們的類加載器要加載一個(gè)類的時(shí)候,它首先會(huì)委派給它的父親去加載,但是如果它的父親沒(méi)找到就會(huì)把這個(gè)事交給他的孩子自己去完成了。

這就是雙親委派機(jī)制。

舉個(gè)例子,假如我們的應(yīng)用程序類加載器要加載一個(gè)類A,那么首先它會(huì)先回家找它老爸?jǐn)U展類加載器,問(wèn)問(wèn)“老爸,你那有這個(gè)類A嗎?”

然后擴(kuò)展類加載器接到這個(gè)請(qǐng)求之后,同樣也懶得處理,再去找它爺爺啟動(dòng)類加載器。

它爺爺找了一圈沒(méi)找到類A,很生氣,就對(duì)擴(kuò)展類加載器說(shuō),“我這沒(méi)有,你自己找去!”

然后擴(kuò)展類加載器就灰溜溜的自己找了一圈,同樣也沒(méi)找到,這時(shí)候就找到應(yīng)用類加載器了,說(shuō):“我這哪有你這個(gè)類A,這明明是你自己應(yīng)該干的活,愛(ài)上哪找上哪找去,我不管了”。

這時(shí)候應(yīng)用類加載器就只能自己去處理了,找了一圈發(fā)現(xiàn)找到了類A,就把它加載到j(luò)vm內(nèi)存中了。

相信大家看了這個(gè)例子應(yīng)該很容易理解了吧。

所以假設(shè)我們自己創(chuàng)建了一個(gè)類java.lang.String,它是不會(huì)被應(yīng)用類加載器加載到內(nèi)存中的,因?yàn)楦割愔锌梢哉业竭@個(gè)類,就直接給加載到內(nèi)存中了。

聊聊驗(yàn)證、準(zhǔn)備、解析、初始化階段

聊完了加載,我們?cè)賮?lái)看看驗(yàn)證、準(zhǔn)備、解析、初始化這幾個(gè)階段jvm都做了什么。

1.驗(yàn)證階段

這一步其實(shí)很容易理解,就是jvm根據(jù)java規(guī)范,來(lái)校驗(yàn)?zāi)慵虞d進(jìn)來(lái)的class文件中的內(nèi)容是否符合規(guī)范,如果不符合規(guī)范jvm是無(wú)法正常運(yùn)行的。

所以在加載后,首先就是驗(yàn)證階段。

2.準(zhǔn)備階段

假設(shè)我們有一個(gè)類A,剛剛加載并通過(guò)了驗(yàn)證,那么就會(huì)進(jìn)行準(zhǔn)備工作。

這個(gè)準(zhǔn)備工作其實(shí)就是給類A分配一定的內(nèi)存空間,然后給里面的靜態(tài)變量(static修飾的變量)也分配內(nèi)存空間,并賦初始值。

3.解析階段

這個(gè)階段干的事實(shí)際上是把符號(hào)引用替換為直接引用,這一過(guò)程網(wǎng)上有很多資料,還是比較復(fù)雜的,如果感興趣小伙伴們可以自己查閱一下資料。

實(shí)際工作中也很少會(huì)接觸這部分的內(nèi)容,所以我們知道有這么個(gè)階段就可以了。

4.初始化階段

在準(zhǔn)備階段,我們把類A的內(nèi)存已經(jīng)分配完了,那么初始化階段要做些什么事呢?我們先看一下類A的代碼

public class A {
  private static String i=System.getProperty("i");
}

準(zhǔn)備階段我們只是給變量i分配了內(nèi)存空間,并賦值了初始值,但是后邊的System.getProperty("i")是不會(huì)執(zhí)行的。

沒(méi)錯(cuò),這部分代碼就是在初始化階段執(zhí)行的,另外靜態(tài)代碼塊也會(huì)在這一階段執(zhí)行。

舉個(gè)例子,比如我們新建一個(gè)對(duì)象new A(),此時(shí)就會(huì)觸發(fā)從加載到初始化的全過(guò)程,把這個(gè)類準(zhǔn)備好并創(chuàng)建一個(gè)實(shí)例對(duì)象。

此外這里有一個(gè)規(guī)則,如果類A繼承了類B,那么在初始化類A的時(shí)候,如果發(fā)現(xiàn)類B還沒(méi)有初始化,會(huì)先初始化類B。

擴(kuò)展

到這里關(guān)于JVM的類加載機(jī)制其實(shí)就已經(jīng)說(shuō)完了,王子再給大家擴(kuò)展一個(gè)小知識(shí)點(diǎn)。

小伙伴們想過(guò)沒(méi)有,Tomcat也是用java開(kāi)發(fā)的,那么它的類加載機(jī)制是什么樣的呢,為什么就能支持jsp呢?

其實(shí)它就是利用了自定義類加載器這一機(jī)制,自己自定義了很多類加載器,整體的結(jié)構(gòu)如下:

Tomcat自定義了這么多的類加載器,用來(lái)加載它自己的核心類庫(kù),并且Tomcat是打破了雙親委派機(jī)制的,感興趣的小伙伴可以自己去查資料了解一下,王子就不在本篇文章長(zhǎng)篇大論來(lái)聊Tomcat了。

總結(jié)

今天我們聊的內(nèi)容還是jvm中比較基礎(chǔ)的部分,以后的文章我們?cè)俾钊耄ヌ剿鱦vm的底層原理,如果對(duì)JVM感興趣的小伙伴可以關(guān)注王子的后續(xù)文章哦,我們可以一步一個(gè)腳印的逐步分解JVM,去了解JVM的垃圾回收機(jī)制、性能調(diào)優(yōu)等等實(shí)用性問(wèn)題,讓你面對(duì)JVM的面試或者生產(chǎn)實(shí)踐也可以游刃有余。

那我們下次見(jiàn)。

以上就是通俗講解JVM的類加載機(jī)制的詳細(xì)內(nèi)容,更多關(guān)于JVM 類加載機(jī)制的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java批量插入數(shù)據(jù)的幾種方法

    java批量插入數(shù)據(jù)的幾種方法

    這篇文章主要給大家介紹了關(guān)于java批量插入數(shù)據(jù)的幾種方法,大家在Java項(xiàng)目中經(jīng)常會(huì)出現(xiàn)大量向數(shù)據(jù)庫(kù)中插入的情況,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • Java編程實(shí)現(xiàn)漢字按字母順序排序的方法示例

    Java編程實(shí)現(xiàn)漢字按字母順序排序的方法示例

    這篇文章主要介紹了Java編程實(shí)現(xiàn)漢字按字母順序排序的方法,結(jié)合具體實(shí)例形式分析了java編碼轉(zhuǎn)換及字母排序相關(guān)操作技巧,需要的朋友可以參考下
    2017-07-07
  • Kotlin實(shí)現(xiàn)靜態(tài)方法

    Kotlin實(shí)現(xiàn)靜態(tài)方法

    這篇文章主要介紹了Kotlin實(shí)現(xiàn)靜態(tài)方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • 解決SpringBoot多模塊發(fā)布時(shí)99%的問(wèn)題

    解決SpringBoot多模塊發(fā)布時(shí)99%的問(wèn)題

    本文歸納了以下 8 個(gè)原則和發(fā)布時(shí)經(jīng)常出現(xiàn)的 4 個(gè)問(wèn)題的解決方案,掌握了這些原則和解決方案,幾乎可以解決絕大數(shù)SpringBoot發(fā)布問(wèn)題
    2019-07-07
  • 詳解Springboot集成sentinel實(shí)現(xiàn)接口限流入門

    詳解Springboot集成sentinel實(shí)現(xiàn)接口限流入門

    這篇文章主要介紹了詳解Springboot集成sentinel實(shí)現(xiàn)接口限流入門,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • java 中@Deprecated 注解的實(shí)例詳解

    java 中@Deprecated 注解的實(shí)例詳解

    這篇文章主要介紹了java 中@Deprecated 注解的實(shí)例詳解的相關(guān)資料,這里對(duì)@Deprecated注解進(jìn)行了詳細(xì)介紹,希望能幫助到大家,需要的朋友可以參考下
    2017-08-08
  • Java Date類常用示例_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java Date類常用示例_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    在JDK1.0中,Date類是唯一的一個(gè)代表時(shí)間的類,但是由于Date類不便于實(shí)現(xiàn)國(guó)際化,所以從JDK1.1版本開(kāi)始,推薦使用Calendar類進(jìn)行時(shí)間和日期處理。這里簡(jiǎn)單介紹一下Date類的使用,需要的朋友可以參考下
    2017-05-05
  • java 終止線程的4種方式小結(jié)

    java 終止線程的4種方式小結(jié)

    本文主要介紹了java終止線程的4種方式小結(jié),包含布爾標(biāo)志位,interrupt()方法,stop()方法和Thread.interrupt()方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • SpringCloud Alibaba使用Seata處理分布式事務(wù)的技巧

    SpringCloud Alibaba使用Seata處理分布式事務(wù)的技巧

    在傳統(tǒng)的單體項(xiàng)目中,我們使用@Transactional注解就能實(shí)現(xiàn)基本的ACID事務(wù)了,隨著微服務(wù)架構(gòu)的引入,需要對(duì)數(shù)據(jù)庫(kù)進(jìn)行分庫(kù)分表,每個(gè)服務(wù)擁有自己的數(shù)據(jù)庫(kù),這樣傳統(tǒng)的事務(wù)就不起作用了,那么我們?nèi)绾伪WC多個(gè)服務(wù)中數(shù)據(jù)的一致性呢?跟隨小編一起通過(guò)本文了解下吧
    2021-06-06
  • java實(shí)現(xiàn)四子棋游戲

    java實(shí)現(xiàn)四子棋游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)四子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-03-03

最新評(píng)論