深入理解JVM之類載入
JVM將類載入過程分為三個步驟:裝載、連結、初始化。裝載、連結完成後,即可將二進位制位元組碼轉換為Class物件,
初始化過程不是載入類時必須觸發的,只要求在初次使用物件前執行即可,初始化主要給靜態變數賦值、呼叫
一,裝載(load)
JVM透過類的全限定名(com.sun.HelloWorld)及類載入器(ClassLoader例項)完成類的載入,相應地,
也是用這兩個元素來標識一個被載入了的類:類的全限定名 + ClassLoader例項ID
二,連結
對二進位制位元組碼的格式進行校驗、初始化類中的靜態變數、解析類中呼叫的介面、類。
校驗過程中,如果格式不符則丟擲VerifyError,如果碰到要引用其它介面或類,也會進行載入,如果載入過程失敗,
則會丟擲NoClassDefFoundError。
完成校驗以後,JVM初始化類中的靜態變數,並將其賦值為預設值。
最後對類中所有屬性、方法進行校驗,以確保其要呼叫的屬性、方法存在,以及具備相應的許可權(如public、private等),
如果這個階段失敗,可能會造成NoSuchMethodError、NoSuchFieldError等錯誤。
三,初始化
初始化過程即執行類中的靜態初始化程式碼、構造程式碼及靜態屬性的初始化,以下幾種情況會觸發初始化過程:
1,呼叫new
2,反射呼叫了類中的方法
3,子類呼叫了初始化
4,JVM啟動過程中指定的初始化類
四,類載入器
JVM的類載入透過ClassLoader及其子類來完成,分為Bootstrap ClassLoader、Extension ClassLoader、System ClassLoader及User-Defined ClassLoader,除了Bootstrap外,剩下3個都是有父子層級關係的。
Bootstrap,此類不是ClassLoader的子類,程式碼中無法拿到這個物件,JDK啟動時會初始化該ClassLoader,並由它載入$JAVA_HOME/jre/rt.jar中所有class的載入,這些class是java規範定義的所有介面及實現(java.lang, java.util等)。
Extension載入$JAVA_HOME/jre/ext/*.jar。
System載入啟動引數中指定的Classpath中的jar,簡言之,使用者寫的class會由它載入,Sun JDK中對應的實現類為AppClassLoader
User-Defined ClassLoader是開發人員自行實現的ClassLoader,可用於載入非classpath中的jar,如從網路上下載的jar或二進位制。
之前說過,ClassLoader是有父子層級關係的,當載入class時,首先會去已載入的class中查詢,如果有,直接返回,否則判斷parentClassLoader是否存在,存在,呼叫parent . loadClass,不存在,呼叫findBootstrapClassOrNull。如果最後還是找不到,則呼叫findClass,該方法預設直接throw new ClassNotFoundException,需要ClassLoader子類自己覆蓋。
但載入時也可以不採用以上順序,可以直接在當前的ClassLoader中尋找,如Class.forName(),JVM會直接透過當前ClassLoader(也就是執行Class.forName所在類的ClassLoader,caller.getClassLoader0() native方法)載入Class。
由於JVM是採用類全限定名+ClassLoader例項來判斷是否載入了某個類,所以,如果直接從當前classLoader直接載入的話,
會造成樹上多個不同的classloader中都載入了某class(某處Class.forName,某處直接new),且這些Class的例項物件都不同。JVM會保證同一個ClassLoader例項中只能載入一次同樣名稱的Class,因此可以藉助此來實現類隔離的需求。
但也會有問題,例如ClassCastException,因此在載入類時,儘量保證從根到最下層的ClassLoader上的Class只載入一次。
當ClassLoader在整個樹中都沒找到Class物件,則丟擲ClassNotFoundException
類載入的常見異常:
1,ClassNotFoundException:ClassLoader載入類時未找到該類。
2,NoClassDefFoundError:在載入的類中引用到其它的類不存在,或者載入引用的類失敗。
3,ClassCastException:兩個物件的Class有不同的ClassLoader載入。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28912557/viewspace-1129390/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 深入理解JVM類載入器JVM
- 深入理解JVM類載入機制JVM
- 深入理解JVM——(四)類載入機制JVM
- 深入理解JVM(六)——類載入器原理JVM
- 深入理解JVM虛擬機器6:深入理解JVM類載入機制JVM虛擬機
- 深入理解JVM(四)類載入的時機JVM
- JVM 之類載入JVM
- 【JVM】JVM之類載入器JVM
- 理解JVM(四):JVM類載入機制JVM
- 深入理解JVM,虛擬機器類載入機制JVM虛擬機
- 深入理解JVM(③)虛擬機器的類載入時機JVM虛擬機
- 深入理解JVM(③)虛擬機器的類載入過程JVM虛擬機
- 要點提煉| 理解JVM之類載入機制JVM
- 深入探究JVM之類載入與雙親委派機制JVM
- Java類載入器深入理解Java
- 【JVM】JVM系列之類載入機制(四)JVM
- 深入理解jvm-2Edition-虛擬機器類載入機制JVM虛擬機
- JVM之類載入器ClassLoaderJVM
- jvm類載入JVM
- [JVM]類載入JVM
- 深入理解JVM之OOMJVMOOM
- 深入理解JVM(③)虛擬機器的類載入器(雙親委派模型)JVM虛擬機模型
- 深入理解OSGi類載入機制
- JVM系列之類載入流程-自定義類載入器JVM
- JVM之類載入機制總結JVM
- JVM之類載入器子系統JVM
- 深入理解JVM類檔案格式JVM
- 深入淺出JVM(三)之HotSpot虛擬機器類載入機制JVMHotSpot虛擬機
- 深入理解JVM讀書筆記三: 虛擬機器類載入機制JVM筆記虛擬機
- Java基礎——深入理解類的載入Java
- 深入理解Java類載入器(ClassLoader)Java
- JVM-類載入JVM
- 類載入器(JVM)JVM
- JVM核心之JVM執行和類載入全過程JVM
- JVM入門--類載入器JVM
- 深入理解Java:類載入機制及反射Java反射
- 深入理解 JVM 之 JVM 記憶體結構JVM記憶體
- 深入理解JVM(1)之--JVM記憶體模型JVM記憶體模型