Java虛擬機(jī)類加載器之雙親委派機(jī)制模型案例
1. 雙親委派模型是什么?
當(dāng)某個(gè)類加載器需要加載某個(gè).class字節(jié)碼文件時(shí),它首先把這個(gè)任務(wù)委托給它的上級(jí)類加載器,遞歸這個(gè)操作,如果上級(jí)的類加載器沒(méi)有加載,自己才會(huì)去加載這個(gè)類。
2. 雙親委派模型的工作原理?
1.如果一個(gè)類加載器收到了類加載的請(qǐng)求,它首先不會(huì)自己去嘗試加載這個(gè)類,而是把這個(gè)請(qǐng)求委派給父類加載器去執(zhí)行;
2.如果父類加載器還存在其父類加載器,則進(jìn)一步向上委托,依次遞歸,請(qǐng)求最終將到達(dá)頂層的啟動(dòng)類加載器;(每一個(gè)層次的類加載器都是如此,因此所有的加載請(qǐng)求最終都應(yīng)該傳送到最頂層的啟動(dòng)類加載器中。)
3.如果父類加載器可以完成類加載任務(wù),就成功返回;倘若父類加載器反饋?zhàn)约簾o(wú)法完成這個(gè)加載請(qǐng)求(它的搜索范圍中沒(méi)有找到所需的類)時(shí),子加載器才會(huì)嘗試自己去完成加載。
以上便是雙親委派模型的工作原理。
雙親委派模型對(duì)于保證Java程序的穩(wěn)定運(yùn)作極為重要,但它的實(shí)現(xiàn)卻異常簡(jiǎn)單,用以實(shí)現(xiàn)雙親委
派的代碼只有短短十余行,全部集中在java.lang.ClassLoader的loadClass()方法之中。
雙親委派模型的核心代碼:
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { // 首先,檢查這類是否已經(jīng)被加載過(guò)了 Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { //如果存在父類加載器,則取找該類的父類加載器 c = parent.loadClass(name, false); } else { //返回由引導(dǎo)類加載器加載的類;如果未找到,則返回 null。 c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // 如果父類加載器拋出ClassNotFoundException異常 // 則說(shuō)明父類加載器無(wú)法完成加載請(qǐng)求 } if (c == null) { // 在父類加載器無(wú)法加載時(shí) // 再調(diào)用本身的findClass方法來(lái)進(jìn)行加載 long t1 = System.nanoTime(); c = findClass(name); // 這是定義類加載器;記錄統(tǒng)計(jì)數(shù)據(jù) sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }
這段源碼邏輯:
1.首先,檢查請(qǐng)求加載的類型是否已經(jīng)被加載,倘若沒(méi)有則調(diào)用父類加載器loadClass()方法;
2.如果父類加載器為空,則默認(rèn)使用啟動(dòng)類加載器作為父加載器。
3.如果父類加載器加載失敗,拋出ClassNotFoundException異常,這時(shí)候才調(diào)用自己的findClass()方法嘗試進(jìn)行加載。
可參考網(wǎng)上的雙親委派模型流程圖:
3. 雙親委派機(jī)制的優(yōu)勢(shì)?
1.保證基礎(chǔ)類僅加載一次,不會(huì)讓JVM中存在重名的類。
防止重復(fù)加載同一個(gè).class文件,比如String.class,每次加載都委托給父加載器,最終都是BootstrapClassLoader,都保證java核心類都是BootstrapClassLoader加載的,加載過(guò)了,就不用再加載一遍,保證了java的安全與穩(wěn)定性。
2.保護(hù)程序安全,防止核心.class文件被隨意篡改。
通過(guò)委托方式,不會(huì)去篡改核心.class,即使篡改也不會(huì)去加載,即使加載也不會(huì)是同一個(gè).class對(duì)象了。不同的加載器加載同一個(gè).class也不是同一個(gè)Class對(duì)象。這樣保證了Class執(zhí)行安全。
到此這篇關(guān)于Java虛擬機(jī)類加載器之雙親委派機(jī)制模型案例的文章就介紹到這了,更多相關(guān)Java虛擬機(jī)類加載器之雙親委派內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java中Integer包裝類裝箱的一個(gè)細(xì)節(jié)詳解
Java中的Integer是int的包裝類型,下面這篇文章主要給大家介紹了關(guān)于java中Integer包裝類裝箱的一個(gè)細(xì)節(jié)的相關(guān)資料,文中介紹的這個(gè)細(xì)節(jié)挺重要的,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起看看吧2018-07-07使用CORS實(shí)現(xiàn)JavaWeb跨域請(qǐng)求問(wèn)題的方法
這篇文章主要介紹了使用Cors實(shí)現(xiàn)JavaWeb跨域請(qǐng)求問(wèn)題的方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09feign GET請(qǐng)求不支持對(duì)象傳參的坑及解決
這篇文章主要介紹了feign GET請(qǐng)求不支持對(duì)象傳參的坑及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03MyBatis之傳入?yún)?shù)為list、數(shù)組、map的寫法
這篇文章主要介紹了MyBatis之傳入?yún)?shù)為list、數(shù)組、map的寫法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11SpringBoot啟動(dòng)自動(dòng)終止也不報(bào)錯(cuò)的原因及解決
這篇文章主要介紹了SpringBoot啟動(dòng)自動(dòng)終止也不報(bào)錯(cuò)的原因及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09Spring boot 使用JdbcTemplate訪問(wèn)數(shù)據(jù)庫(kù)
SpringBoot 是為了簡(jiǎn)化 Spring 應(yīng)用的創(chuàng)建、運(yùn)行、調(diào)試、部署等一系列問(wèn)題而誕生的產(chǎn)物。本文重點(diǎn)給大家介紹spring boot 使用JdbcTemplate訪問(wèn)數(shù)據(jù)庫(kù),需要的朋友可以參考下2018-05-05