天天看點

JVM classLoader

1)三個類加載器:

bootstrap classloader - 引導(也稱為原始)類加載器,它負責加載Java的核心類。

extension classloader - 擴充類加載器,它負責加載JRE的擴充目錄中JAR的類包。

system classloader - 系統(也稱為應用)類加載器,加載應用程式的類。

bootstrap classloader不是一個真正的ClassLoader執行個體

   JVM在運作時會産生三個ClassLoader:Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader

AppClassLoader的Parent是ExtClassLoader,而ExtClassLoader的Parent為Bootstrap ClassLoader

2)擷取引導類加載器加載了哪些類:

URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();

for (int i = 0; i < urls.length; i++) {

System.out.println(urls[i].toExternalForm());

}

在jre1.5中,該段輸出: 

file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/lib/resources.jar

       file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/lib/rt.jar

       file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/lib/sunrsasign.jar

       file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/lib/jsse.jar

       file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/lib/jce.jar

       file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/lib/charsets.jar

       file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/classes

即為所加載的java的核心類

3)擷取應用類加載器:

ClassLoader.getSystemClassLoader()

4)JVM類加載機制:全盤負責委托機制

      全盤負責:當一個classloader加載一個Class的時候,這個Class所依賴的和引用的所有Class也由這個classloader負責載入,除非是顯式的使用另外一個classloader載入;

     委托機制:先讓parent(父)類加載器(而不是super,它與parent classloader類不是繼承關系)尋找,隻有在parent找不到的時候才從自己的類路徑中去尋找。

Cache機制:如果cache中儲存了這個Class就直接傳回它,如果沒有才從檔案中讀取和轉換成Class,并存入cache,這就是為什麼我們修改了Class但是必須重新啟動JVM才能生效的原因。

5)每個ClassLoader加載Class的過程是:

1.檢測此Class是否載入過(即在cache中是否有此Class),如果有到8,如果沒有到2

2.如果parent classloader不存在(沒有parent,那parent一定是bootstrap classloader了),到4

3.請求parent classloader載入,如果成功到8,不成功到5

4.請求jvm從bootstrap classloader中載入,如果成功到8

5.尋找Class檔案(從與此classloader相關的類路徑中尋找)。如果找不到則到7.

6.從檔案中載入Class,到8.

7.抛出ClassNotFoundException.

8.傳回Class.

其中5.6步我們可以通過覆寫ClassLoader的findClass方法來實作自己的載入政策。甚至覆寫loadClass方法來實作自己的載入過程。