JVM的類加載
宏觀的看java程序的執(zhí)行

平時(shí)我們寫(xiě)好的java代碼都是以.java作為后綴結(jié)尾的。我們要把這些代碼放到線上運(yùn)行就要對(duì)他們進(jìn)行打包,打成jar包。然后里面的.java文件就會(huì)被編譯成.class。然后我們會(huì)使用類加載器把這些.class的字節(jié)碼文件加載到JVM中。然后JVM會(huì)用內(nèi)部的字節(jié)碼執(zhí)行引擎來(lái)執(zhí)行字節(jié)碼。當(dāng)我們需要哪個(gè)類類加載器就會(huì)從.class文件加載對(duì)應(yīng)的類。
學(xué)習(xí)更多知識(shí),請(qǐng)點(diǎn)擊:https://www.bilibili.com/video/BV1Li4y1P764/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1yy4y147TY/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1yp4y1H7na/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1gA411T7cc/
類加載的步驟
加載: 當(dāng)我們要用到這個(gè)類的時(shí)候,比如類里的main方法入口,或者new了其他類我們就會(huì)通過(guò)這個(gè)類的全限定類名,獲取定義這個(gè)類的字節(jié)流。java的類加載器就實(shí)現(xiàn)通過(guò)類的全限定類名類獲得這個(gè)類的字節(jié)流這個(gè)動(dòng)作。
驗(yàn)證:檢查加載進(jìn)來(lái)的.class文件是否符合Java虛擬機(jī)規(guī)范。
準(zhǔn)備: 為靜態(tài)變量分配內(nèi)存,并且為靜態(tài)變量設(shè)置初始值。
解析:將符號(hào)引用替換為直接引用。
初始化: 執(zhí)行類構(gòu)造器的clinit()方法。clinit方法會(huì)自動(dòng)收集java中類變量的賦值動(dòng)作和靜態(tài)代碼塊。
學(xué)習(xí)更多知識(shí),請(qǐng)點(diǎn)擊:https://www.bilibili.com/video/BV1Li4y1P764/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1yy4y147TY/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1yp4y1H7na/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1gA411T7cc/
類加載器的雙親委派機(jī)制
有哪些類加載器?
啟動(dòng)類加載器:BootStrap ClassLoader:負(fù)責(zé)加載最核心的類庫(kù)。當(dāng)JVM啟動(dòng)的時(shí)候,就會(huì)依托Bootstrap classloader類加載器去加載核心類。
擴(kuò)展類加載器 : extension ClassLoader :負(fù)責(zé)加載lib\ext目錄下的類。
應(yīng)用程序類加載器: application ClassLoader: 負(fù)責(zé)加載ClassPath環(huán)境變量下指定的的路徑中的類。
自定義的類加載器: 自己定義的類加載器去
雙親委派機(jī)制
雙親委派機(jī)制是類加載器之間一個(gè)非常重要的機(jī)制。
工作流程:
一個(gè)類加載器收到了類加載的請(qǐng)求,它首先不會(huì)自己去嘗試加載這個(gè)類,而是把這個(gè)請(qǐng)求委派給父類加載器去完成,每一個(gè)層次的類加載器都是如此。需要注意的是父子類加載器之間的這種關(guān)系不是繼承的關(guān)系來(lái)實(shí)現(xiàn)的,而是組合的關(guān)系來(lái)實(shí)現(xiàn)的。所有的類加載器的請(qǐng)求都會(huì)傳送到頂層的Bootstrap classloader里。只有當(dāng)父類加載器無(wú)法完成這個(gè)加載請(qǐng)求,因?yàn)樗乃阉鞣秶鷽](méi)有找到所需要的類的時(shí)候,子加載器才會(huì)嘗試自己去完成加載。
使用雙親委派機(jī)制來(lái)組織類加載器之間的關(guān)系,的顯而易見(jiàn)的好處就是Java中的類隨著它的類加載器具備了一種自帶優(yōu)先級(jí)的關(guān)系。例如java.lang.Object類,無(wú)論哪一個(gè)類加載器都要加載這個(gè)類,最終都會(huì)委派處于模型最頂端的啟動(dòng)類加載類解析加載,所以O(shè)bject在各個(gè)類加載環(huán)境中都能夠保證是同一個(gè)類,如果沒(méi)有使用雙親委派機(jī)制,如果用戶也編寫(xiě)一個(gè)java.lang.Object放在ClassPath中,那系統(tǒng)會(huì)出現(xiàn)多個(gè)不同的object類。
學(xué)習(xí)更多知識(shí),請(qǐng)點(diǎn)擊:https://www.bilibili.com/video/BV1Li4y1P764/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1yy4y147TY/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1yp4y1H7na/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1gA411T7cc/
接下來(lái)這張圖就是類加載的流程圖

破壞雙親委派機(jī)制
有的時(shí)候我們也需要打破雙親委派機(jī)制。舉個(gè)例子,在Tomcat中我們就打破了雙親委派機(jī)制。Tomcat的類加載機(jī)制是如何設(shè)計(jì)的呢?為什么要破壞呢?
因?yàn)槲覀兊膚eb容器可能會(huì)同時(shí)部署多個(gè)程序,他們依賴的庫(kù)也有來(lái)源于不同的版本的,所以我們對(duì)于每一個(gè)部署的程序都應(yīng)該是獨(dú)立的。
學(xué)習(xí)更多知識(shí),請(qǐng)點(diǎn)擊:https://www.bilibili.com/video/BV1Li4y1P764/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1yy4y147TY/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1yp4y1H7na/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1gA411T7cc/
我們來(lái)看Tomcat是如何實(shí)現(xiàn)的: 具體查閱《深入理解JVM》9.2

學(xué)習(xí)更多知識(shí),請(qǐng)點(diǎn)擊:https://www.bilibili.com/video/BV1Li4y1P764/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1yy4y147TY/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1yp4y1H7na/
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1gA411T7cc/
作者:vegetabledog
鏈接:https://juejin.cn/post/6939875539175866398
來(lái)源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。