旅游網(wǎng)站開發(fā)項(xiàng)目策劃書中國四大軟件外包公司
JVM:雙親委派機(jī)制
- 1. 例子
- 2. 類加載器總結(jié)
- 3. 類加載過程
- 4. 雙親委派模型的執(zhí)行流程:
- 5. 雙親委派模型的好處
1. 例子
Java運(yùn)行時環(huán)境有一個java.lang
包,里面有一個ClassLoader
類
我們自定義一個String
類在java.lang
包下,下面的main方法報(bào)錯。原因是: 根據(jù)雙親委派機(jī)制,會向上找先是找到了應(yīng)用程序加載器(appClassLoader) ,然后向上找擴(kuò)展類加載器(ExtClassLoader),最后找根類加載器(Boot Strap Loader),發(fā)現(xiàn)有String執(zhí)行根加載器的也就是rt.jar
包中的。 其實(shí)就是上級的加載器有的就執(zhí)行上級的
2. 類加載器總結(jié)
JVM 中內(nèi)置了三個重要的 ClassLoader:
BootstrapClassLoader(啟動類加載器)
:最頂層的加載類,由 C++實(shí)現(xiàn),通常表示為 null,并且沒有父級,主要用來加載 JDK 內(nèi)部的核心類庫( %JAVA_HOME%/lib目錄下的 rt.jar 、resources.jar 、charsets.jar等 jar 包和類)以及被 -Xbootclasspath參數(shù)指定的路徑下的所有類。ExtensionClassLoader(擴(kuò)展類加載器)
:主要負(fù)責(zé)加載 %JRE_HOME%/lib/ext 目錄下的 jar 包和類以及被 java.ext.dirs 系統(tǒng)變量所指定的路徑下的所有類。AppClassLoader(應(yīng)用程序類加載器)
:面向我們用戶的加載器,負(fù)責(zé)加載當(dāng)前應(yīng)用 classpath 下的所有 jar 包和類。
簡單來說,類加載器的主要作用就是加載 Java 類的字節(jié)碼( .class 文件)到 JVM 中(在內(nèi)存中生成一個代表該類的 Class 對象)。 字節(jié)碼可以是 Java 源程序(.java文件)經(jīng)過 javac 編譯得來,也可以是通過工具動態(tài)生成或者通過網(wǎng)絡(luò)下載得來。
3. 類加載過程
- 類加載過程:加載->連接->初始化。
- 連接過程又可分為三步:驗(yàn)證->準(zhǔn)備->解析。
加載是類加載過程的第一步,主要完成下面 3 件事情:
- 通過全類名獲取定義此類的二進(jìn)制字節(jié)流
- 將字節(jié)流所代表的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)換為方法區(qū)的運(yùn)行時數(shù)據(jù)結(jié)構(gòu)
- 在內(nèi)存中生成一個代表該類的 Class 對象,作為方法區(qū)這些數(shù)據(jù)的訪問入口
4. 雙親委派模型的執(zhí)行流程:
- 在類加載的時候,系統(tǒng)會首先判斷當(dāng)前類是否被加載過。已經(jīng)被加載的類會直接返回,否則才會嘗試加載(每個父類加載器都會走一遍這個流程)。
- 類加載器在進(jìn)行類加載的時候,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成(調(diào)用父加載器 loadClass()方法來加載類)。這樣的話,所有的請求最終都會傳送到頂層的啟動類加載器 BootstrapClassLoader 中。
- 只有當(dāng)父加載器反饋?zhàn)约簾o法完成這個加載請求(它的搜索范圍中沒有找到所需的類)時,子加載器才會嘗試自己去加載(調(diào)用自己的 findClass() 方法來加載類)。
5. 雙親委派模型的好處
雙親委派模型保證了 Java 程序的穩(wěn)定運(yùn)行,可以避免類的重復(fù)加載(JVM 區(qū)分不同類的方式不僅僅根據(jù)類名,相同的類文件被不同的類加載器加載產(chǎn)生的是兩個不同的類),也保證了 Java 的核心 API 不被篡改。
如果沒有使用雙親委派模型,而是每個類加載器加載自己的話就會出現(xiàn)一些問題,比如我們編寫一個稱為 java.lang.Object
類的話,那么程序運(yùn)行的時候,系統(tǒng)就會出現(xiàn)兩個不同的 Object 類。雙親委派模型可以保證加載的是 JRE 里的那個 Object 類,而不是你寫的 Object 類。這是因?yàn)?AppClassLoader
在加載你的 Object 類時,會委托給 ExtClassLoader 去加載,而ExtClassLoader
又會委托給 BootstrapClassLoader,BootstrapClassLoader
發(fā)現(xiàn)自己已經(jīng)加載過了 Object 類,會直接返回,不會去加載你寫的 Object 類。