JVM(3)——JVM类加载器
一、類加載器簡介
虛擬機設計團隊把類加載階段中的“通過一個類的全限定名來獲取描述此類的二進制字節流”這個動作放到Java虛擬機外部去實現,以便讓應用程序自己決定如何去獲取所需要的類。實現這個動作的代碼模塊被稱為“類加載器”。
類加載器雖然只用于實現類的加載動作,但它在Java程序中起到的作用卻遠遠不限于類加載階段。對于任意一個類,都需要由加載它的類加載器和這個類本身一同確立其在Java虛擬機中的唯一性。比較兩個類是否“相等”,只有在這兩個類是由同一個類加載器加載的前提之下才有意義,否則,即使這兩個類是來源于同一個Class文件,只要加載它們的類加載器不同,那這兩個類就必定不相等。
二、雙親委派模型
站在Java虛擬機的角度講,只存在兩種不同的類加載器:一種是啟動類加載器(Bootstrap?ClassLoader),這個類加載器使用C++語言實現,是虛擬機自身的一部分;另外一種就是所有其他類的加載器,這些類加載器都由Java語言實現,獨立于虛擬機外部,并且全部都繼承自抽象類java.lang.ClassLoader。
類加載器:
?????(1)?啟動類加載器Bootstrap?ClassLoader?:?將存放于<JAVA_HOME>\lib目錄中的,或者被-Xbootclasspath參數所指定的路徑中的,并且是虛擬機識別的(僅按照文件名識別,如?rt.jar?名字不符合的類庫即使放在lib目錄中也不會被加載)類庫加載到虛擬機內存中。啟動類加載器無法被Java程序直接引用。
?????(2)?擴展類加載器Extension?ClassLoader?:將<JAVA_HOME>\lib\ext目錄下的,或者被java.ext.dirs系統變量所指定的路徑中的所有類庫加載,開發者可以直接使用擴展類加載器。
?????(3)應用程序類加載器?Application?ClassLoader?:?負責加載用戶類路徑(ClassPath)上所指定的類庫,開發者可直接使用。
類加載器雙親委派模型如下圖所示:
工作過程:
如果一個類加載器接收到了類加載的請求,它首先把這個請求委托給他的父類加載器去完成,每個層次的類加載器都是如此,因此所有的加載請求都應該傳送到頂層的啟動類加載器中,只有當父加載器反饋自己無法完成這個加載請求(它在搜索范圍中沒有找到所需的類)時,子加載器才會嘗試自己去加載。
好處:
Java類隨著它的類加載器一起具備了一種帶有優先級的層次關系。例如類java.lang.Object,它存放在rt.jar中,無論哪個類加載器要加載這個類,最終都會委派給啟動類加載器進行加載,因此Object類在程序的各種類加載器環境中都是同一個類。相反,如果用戶自己寫了一個名為java.lang.Object的類,并放在程序的Classpath中,那系統中將會出現多個不同的Object類,java類型體系中最基礎的行為也無法保證,應用程序也會變得一片混亂。
三、雙親委派模型的實現
實現雙親委派模型的代碼都集中在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
總結
以上是生活随笔為你收集整理的JVM(3)——JVM类加载器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 醋酸泼尼松片的功效
- 下一篇: JVM(4)——对象访问