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