JVM(3)——JVM类加载器
一、類加載器簡(jiǎn)介
虛擬機(jī)設(shè)計(jì)團(tuán)隊(duì)把類加載階段中的“通過一個(gè)類的全限定名來獲取描述此類的二進(jìn)制字節(jié)流”這個(gè)動(dòng)作放到Java虛擬機(jī)外部去實(shí)現(xiàn),以便讓應(yīng)用程序自己決定如何去獲取所需要的類。實(shí)現(xiàn)這個(gè)動(dòng)作的代碼模塊被稱為“類加載器”。
類加載器雖然只用于實(shí)現(xiàn)類的加載動(dòng)作,但它在Java程序中起到的作用卻遠(yuǎn)遠(yuǎn)不限于類加載階段。對(duì)于任意一個(gè)類,都需要由加載它的類加載器和這個(gè)類本身一同確立其在Java虛擬機(jī)中的唯一性。比較兩個(gè)類是否“相等”,只有在這兩個(gè)類是由同一個(gè)類加載器加載的前提之下才有意義,否則,即使這兩個(gè)類是來源于同一個(gè)Class文件,只要加載它們的類加載器不同,那這兩個(gè)類就必定不相等。
二、雙親委派模型
站在Java虛擬機(jī)的角度講,只存在兩種不同的類加載器:一種是啟動(dòng)類加載器(Bootstrap?ClassLoader),這個(gè)類加載器使用C++語(yǔ)言實(shí)現(xiàn),是虛擬機(jī)自身的一部分;另外一種就是所有其他類的加載器,這些類加載器都由Java語(yǔ)言實(shí)現(xiàn),獨(dú)立于虛擬機(jī)外部,并且全部都繼承自抽象類java.lang.ClassLoader。
類加載器:
?????(1)?啟動(dòng)類加載器Bootstrap?ClassLoader?:?將存放于<JAVA_HOME>\lib目錄中的,或者被-Xbootclasspath參數(shù)所指定的路徑中的,并且是虛擬機(jī)識(shí)別的(僅按照文件名識(shí)別,如?rt.jar?名字不符合的類庫(kù)即使放在lib目錄中也不會(huì)被加載)類庫(kù)加載到虛擬機(jī)內(nèi)存中。啟動(dòng)類加載器無法被Java程序直接引用。
?????(2)?擴(kuò)展類加載器Extension?ClassLoader?:將<JAVA_HOME>\lib\ext目錄下的,或者被java.ext.dirs系統(tǒng)變量所指定的路徑中的所有類庫(kù)加載,開發(fā)者可以直接使用擴(kuò)展類加載器。
?????(3)應(yīng)用程序類加載器?Application?ClassLoader?:?負(fù)責(zé)加載用戶類路徑(ClassPath)上所指定的類庫(kù),開發(fā)者可直接使用。
類加載器雙親委派模型如下圖所示:
工作過程:
如果一個(gè)類加載器接收到了類加載的請(qǐng)求,它首先把這個(gè)請(qǐng)求委托給他的父類加載器去完成,每個(gè)層次的類加載器都是如此,因此所有的加載請(qǐng)求都應(yīng)該傳送到頂層的啟動(dòng)類加載器中,只有當(dāng)父加載器反饋?zhàn)约簾o法完成這個(gè)加載請(qǐng)求(它在搜索范圍中沒有找到所需的類)時(shí),子加載器才會(huì)嘗試自己去加載。
好處:
Java類隨著它的類加載器一起具備了一種帶有優(yōu)先級(jí)的層次關(guān)系。例如類java.lang.Object,它存放在rt.jar中,無論哪個(gè)類加載器要加載這個(gè)類,最終都會(huì)委派給啟動(dòng)類加載器進(jìn)行加載,因此Object類在程序的各種類加載器環(huán)境中都是同一個(gè)類。相反,如果用戶自己寫了一個(gè)名為java.lang.Object的類,并放在程序的Classpath中,那系統(tǒng)中將會(huì)出現(xiàn)多個(gè)不同的Object類,java類型體系中最基礎(chǔ)的行為也無法保證,應(yīng)用程序也會(huì)變得一片混亂。
三、雙親委派模型的實(shí)現(xiàn)
實(shí)現(xiàn)雙親委派模型的代碼都集中在java.lang.ClassLoader的loadClass方法中,如下所示:
protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass<?> c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// If still not found, then invoke findClass in order// to find the class.long t1 = System.nanoTime();c = findClass(name);// this is the defining class loader; record the statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}}
參考資料:
http://www.cnblogs.com/lanxuezaipiao/p/4138511.html
總結(jié)
以上是生活随笔為你收集整理的JVM(3)——JVM类加载器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 醋酸泼尼松片的功效
- 下一篇: JVM(4)——对象访问