溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

什么是JVM的類加載及內(nèi)存區(qū)域

發(fā)布時(shí)間:2021-09-10 14:19:24 來(lái)源:億速云 閱讀:142 作者:柒染 欄目:大數(shù)據(jù)

這篇文章將為大家詳細(xì)講解有關(guān)什么是JVM的類加載及內(nèi)存區(qū)域,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

一、JVM加載類的過(guò)程

  • 加載,加載為按需加載,主線程需要用到一個(gè)類才開(kāi)始加載一個(gè)類。

  • 驗(yàn)證,簡(jiǎn)而言之就是校驗(yàn)class內(nèi)容是否符合指定規(guī)范

  • 準(zhǔn)備,為類變量分配內(nèi)存空間,并初始默認(rèn)值。

  • 初始化,執(zhí)行類的初始化代碼(靜態(tài)代碼塊,靜態(tài)賦值代碼),注:初始化會(huì)檢驗(yàn)父類是否初始化,沒(méi)有則必須先初始化父類。

  • 使用

  • 卸載

二、類加載器

種類

  • 啟動(dòng)類加載器-Bootstrap ClassLoader,用于加載Java核心類庫(kù)-java安裝目錄下的lib目錄下的class。

  • 擴(kuò)展類加載器-Extension ClassLoader,用于加載java下的一些擴(kuò)展類庫(kù)-java安裝目錄lib\ext下的class。

  • 應(yīng)用程序類加載器-Application ClassLoader,加載項(xiàng)目ClassPath下所的class。

  • 自定義類加載器,自己定義的類加載器

雙親委派機(jī)制

意思就是即優(yōu)先讓父ClassLoader去加載。原因是避免重復(fù)加載,保證應(yīng)用的classPath下的Class對(duì)象在內(nèi)存中的唯一性。

層次圖

什么是JVM的類加載及內(nèi)存區(qū)域

tomcat破壞雙親委派

tomcat作為java編碼的web容器,本身也是在jvm中運(yùn)行,怎么讓基于tomcat容器的各個(gè)web應(yīng)用正常運(yùn)行,使得各個(gè)web應(yīng)用包含的應(yīng)用的class不會(huì)亂套,必須破壞雙親委派機(jī)制,為每一個(gè)web應(yīng)用的class都用不同的類加載器去加載。

  • tomcat的類加載器層次圖 什么是JVM的類加載及內(nèi)存區(qū)域

其中:

common、catalina、shared負(fù)責(zé)加載tomcat自己的核心類庫(kù),webApp加載web應(yīng)用的class(隔離web應(yīng)用引用的三方類庫(kù)),jsp加載器加載JSP(每個(gè)JSP文件都對(duì)應(yīng)一個(gè)Jsp類加載器,jsp加載器支持熱加載,即Jsp只要修改,就重新加載一次覆蓋原來(lái)的jsp)。

通過(guò)tomcat的類加載機(jī)制,可以達(dá)成以下目標(biāo):

  • tomcat支持各個(gè)web引用中不同版本的三方類庫(kù)相互隔離。

  • 同一個(gè)第三方類庫(kù)的相同版本在不同web應(yīng)用可以共享。

  • tomcat自身依賴的類庫(kù)需要與應(yīng)用依賴的類庫(kù)隔離 。

  • jsp需要支持修改后不用重啟tomcat即可生效 為了上面類加載隔離和類更新不用重啟,定制開(kāi)發(fā)各種的類加載器。

自定義類加載器的作用

  • 實(shí)際中,可以從Web服務(wù)器、數(shù)據(jù)庫(kù)或緩存服務(wù)器獲取bytes數(shù)組,這就不是系統(tǒng)類加載器能做到的了。

  • 可以從不同的路徑中獲取同一個(gè)類的不同class對(duì)象,可以實(shí)現(xiàn)隔離,一個(gè)復(fù)雜的程序,內(nèi)部可能按模塊組織,不同模塊可能使用同一個(gè)類,但使用的是不同版本,如果使用同一個(gè)類加載器,它們是無(wú)法共存的,不同模塊使用不同的類加載器就可以實(shí)現(xiàn)隔離,Tomcat使用它隔離不同的Web應(yīng)用,OSGI使用它隔離不同模塊。

  • 可以實(shí)現(xiàn)熱部署。使用同一個(gè)ClassLoader,類只會(huì)被加載一次,加載后,即使class文件已經(jīng)變了,再次加載,得到的也還是原來(lái)的Class對(duì)象,而使用自定義類加載器,則可以先創(chuàng)建一個(gè)新的ClassLoader,再用它加載Class,得到的Class對(duì)象就是新的,從而實(shí)現(xiàn)動(dòng)態(tài)更新。

三、JVM內(nèi)存區(qū)域劃分

方法區(qū)(1.8之后叫metaspace-元數(shù)據(jù)空間)

存放類的元數(shù)據(jù)信息,可以理解為反射獲取的Class對(duì)象的哪些信息。

程序計(jì)數(shù)器

  • 記錄當(dāng)前執(zhí)行的class文件中字節(jié)碼指令的位置

  • 與線程是一對(duì)一的關(guān)系,每個(gè)線程都會(huì)有自己的一個(gè)程序計(jì)數(shù)器

一個(gè)程序計(jì)數(shù)器對(duì)應(yīng)一個(gè)線程、一個(gè)線程對(duì)應(yīng)一個(gè)棧、一個(gè)棧由一個(gè)個(gè)棧幀組成,一個(gè)方法對(duì)應(yīng)一個(gè)棧幀,棧幀包含局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口(相當(dāng)于結(jié)束方法時(shí)需要跳轉(zhuǎn)的位置)。棧幀在調(diào)用方法的時(shí)候進(jìn)棧,方法結(jié)束的時(shí)候出棧。

  • 存放對(duì)象數(shù)據(jù)(上述棧中只存在對(duì)象的引用(即堆內(nèi)存中對(duì)象的地址)或基本數(shù)據(jù)類型的值)

  • 所有線程共享

  • 當(dāng)引用變量地址數(shù)據(jù)出棧時(shí),堆中的內(nèi)存釋放由JVM控制回收

其他內(nèi)存區(qū)域

  • 執(zhí)行native方法會(huì)有線程對(duì)應(yīng)的本地方法棧。

  • NIO中ByteBuffer類方法:allocateDirect(int capacity)-堆外分配內(nèi)存空間返回DirectBuffer,通過(guò)DirectBuffer的Api可以操作堆外內(nèi)存。

圖示

什么是JVM的類加載及內(nèi)存區(qū)域

關(guān)于什么是JVM的類加載及內(nèi)存區(qū)域就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

jvm
AI