淺談java classloader

類加載器三杰

jvm有三類classloader,分別是bootstrapclassloader,extendedclassloader以及systemclassloader。

bootstrap classloader是系統(tǒng)在啟動jvm時默認加載的。當用戶在命令行輸入java Test時,系統(tǒng)會首先加載jvm。在windows系統(tǒng)下,jvm的路徑通常位于%JAVA_HOME%/jdk/jre/client/jvm.dll和%JAVA_HOME%/jdk/jre/server/jvm.dll.

bootstrap classloader加載后,會載入extended classloader,并將extended classloader的父類設為bootstrap classloader。然后,bootstrap classloader接著載入system classloader,并將system classloader的父類設為extended classloader。至此,bootstrap--extended--system三級繼承結構形成。

bootstrap classloader在jvm啟動之后自動加載。bootstrap ?classloader由c實現(xiàn),不屬于java類。

extended classloader由java實現(xiàn),通常為sun.misc.Lancher$ExtClassLoader.

system classloader由java實現(xiàn),通常為sun.misc.Lancher$AppClassLoader.

其中,

bootstrap classloader負責加載sun.boot.class.path路徑下的.class文件以及jar包。

extended classloader負責加載java.ext.dirs路徑下的.class文件以及jar包。

system classloader負責加載java.class.path路徑下的.class文件以及jar包。

sun.boot.class.path通常對應環(huán)境變量CLASSPATH的路徑。

java.ext.dirs通常對應JAVA_HOME/jre/lib/ext目錄。

java.class.path對應用戶自身的類路徑。

類加載到何處

據(jù)可靠情報,jvm由方法區(qū),堆,棧,pc寄存器和本地方法棧構成。類加載器的任務就是將class二進制文件加載到方法區(qū),供虛擬機模制出在堆中存放的對象。

雙親委托機制

classloader加載類的過程為:

1.檢查被加載類是否被加載。

2.如果沒有被加載則調(diào)用父classloader加載該類。

如果1、2不成功,則仍由自身進行類加載。

這種機制又叫雙親委派機制。

雙親委派機制的好處是,避免多個類加載器加載同一個類的不同拷貝到內(nèi)存(jvm的方法區(qū))中。因為如果類A由ClassLoaderA加載,同時,又被ClassLoaderB加載,這樣,內(nèi)存中就會存在兩份不同的A的定義,于是形成A既是ClassLoaderA罩的,又是ClassLoaderB罩著,造成災難性后果。

用戶自定義類的加載順序通常為:

首先調(diào)用AppClassLoader加載類,AppClassLoader調(diào)用ExtClassLoader,ExtClassLoader調(diào)用BootClassLoader,BootClassLoader在sun.boot.class.path尋找改類,沒找到,加載失??;ExtClassLoader也未加載類,失敗,最后由AppClassLoader加載成功。從這個加載順序可以看出來,三個類加載器的對類的可見性是不同的。

java中的類是由java的全名以及類的classloader來限定的。只有當二者完全一樣才會認為是同一個類。否則是不同的類。因此,可以定義一個同名的類,包名也一樣,只要保證該類被不同的類加載器加載即可。

當前類加載器和線程上下文類加載器

當前類加載器

當前類加載器是指當前方法所在的類使用的類加載器。在程序中使用Class.forName或者Class.getResource抑或Class.class時就是使用的該類加載器。

線程上下文類加載器

線程上下文類加載器可以不遵循雙親委派機制。線程的上下文類加載器有Thread.currentThread().setContextClassLoader()來為當前線程設置線程上下文類加載器。如果沒有設置當前線程的上下文類加載器,則繼承父類的上下文類加載器。

為什么還需要線程上下文類加載器?

考慮一種情況,當我們的程序必須由jvm的核心代碼去加載第三方類的時候。比如jndi,jndi的核心是rt.jar包中實現(xiàn)的,由Bootstrap classloader負責加載,但是jndi必須加載第三方廠商的具體的jndi實現(xiàn),這個時候調(diào)用Bootstrap加載只對其子類加載器可見的類,就會出現(xiàn)失敗。這個時候就可以使用線程上下文類加載器。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Java8張圖 11、字符串不變性 12、equals()方法、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,896評論 0 11
  • ClassLoader翻譯過來就是類加載器,普通的java開發(fā)者其實用到的不多,但對于某些框架開發(fā)者來說卻非常常見...
    時待吾閱讀 1,166評論 0 1
  • 0、前言 讀完本文,你將了解到: 一、為什么說Jabalpur語言是跨平臺的 二、Java虛擬機啟動、加載類過程分...
    vivi_wong閱讀 1,381評論 0 10
  • 作者:成 富, 軟件工程師, IBM 中國軟件開發(fā)中心 類加載器(class loader)是 Java?中的一個...
    Android技術研究閱讀 3,979評論 0 74
  • 網(wǎng)絡協(xié)議 兩臺計算機要實現(xiàn)通訊必須遵守同一個規(guī)則,這就好比兩個人交流,只會英文和只會中文的因為沒有共同的語言(規(guī)則...
    空白Null閱讀 2,224評論 0 4

友情鏈接更多精彩內(nèi)容