java 雙親委派機制 的思考


先上圖,看一下加載器。



151224_tHEL_1990220.png

1、BootStrapClassLoader:啓動類加載器,該ClassLoader是在啓動時候創建的,是寫在JVM內核裏的,它不是一個字節碼文件,是由c++編寫的二進制代碼,所以開發者無法獲取到該啓動類的引用,也就不能通過引用來進行操作。這個加載器是加載$JAVA_HOME/jre/lib下面的類庫(或者通過參數-Xbootclasspath指定)。


2、EXTClassLoader:擴展類加載器,ExtClassLoader會加載 $JAVA_HOME/jre/lib/ext下的類庫(或者通過參數-Djava.ext.dirs指定)。


3、AppClassLoader:應用程序加載器,會加載java環境變量CLASSPATH所指定的路徑下的類庫,而CLASSPATH所指定的路徑可以通過Systemn.getProperty("java.class.path")獲取,該變量可以覆蓋。


4、CustomClassLoader:自定義加載器,就是用戶自己定義的CLassLoader,比如tomcat的standardClassLoader屬於這一類。


ClassLoader雙親委派機制:

1、當APPClassLoader加載一個class時,它首先不會自己去加載這個類,而是把類加載請求委派給父類加載器EXTClassloader去完成。

2、當EXTClassLoader加載一個class時,它首先不會去嘗試加載這個類,而是把類加載請求委派給BootStrapClassLoader去完成。

3、如果BottStrapClassLoader加載失敗,會使用EXTClassLoader去嘗試加載。

4、若EXTClassLoader也加載失敗,則會使用APPClassLoader來加載,如果APPClassLoader也加載失敗,則會報出異常ClassNotFundException.


委派機制具體含義和意義:

當java虛擬機要加載一個類時,到底要排除哪個類加載器去加載呢?

比如:當前線程的類加載器要去加載線程中一個類A,如果這個類A中引用了類B,java虛擬機將使用加載類A的加載器去加載類B。類B再使用的時候如果發現類B已經加載了,就不去加載這個類B了。


我覺得其意義是防止內存中出現多份同樣的字節碼。

如果不用委託而是自己加載自己的,那麼類A就會加載一份System字節碼,然後類B又會加載一份System字節碼,這樣內存中就出現了兩份System字節碼。

如果使用委託機制,會遞歸的向父類查找,也就是首選用Bootstrap嘗試加載,如果找不到再向下。這裏的System就能在Bootstrap中找到然後加載,如果此時類B也要加載System,也從Bootstrap開始,此時Bootstrap發現已經加載過了System那麼直接返回內存中的System即可而不需要重新加載,這樣內存中就只有一份System的字節碼了。

 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章