成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

最新版JDK15的JVM類加載器詳解

開發 后端
由C/C++實現,啟動類加載器,屬最高層,JVM啟動時創建,通常由與os相關的本地代碼實現,是最根基的類加載器。

 [[379155]]

1 類加載器

在類加載器家族中存在著類似人類社會的權力等級制度:

1.1 Bootstrap

由C/C++實現,啟動類加載器,屬最高層,JVM啟動時創建,通常由與os相關的本地代碼實現,是最根基的類加載器。

JDK8 時

需要注意的是,Bootstrap ClassLoader智慧加載特定名稱的類庫,比如rt.jar.這意味我們自定義的jar扔到\jre\lib也不會被加載.

負責將/jre/lib或- Xbootclasspath參數指定的路徑中的,且是虛擬機識別的類庫加載到內存中(按照名字識別,比如rt.jar,對于不能識別的文件不予裝載),比如:

  • Object
  • System
  • String
  • Java運行時的rt.jar等jar包
  • 系統屬性sun.boot.class.path指定的目錄中特定名稱的jar包

在JVM啟動時,通過Bootstrap ClassLoader加載rt.jar,并初始化sun.misc.Launcher從而創建Extension ClassLoader和Application ClassLoader的實例。

查看Bootstrap ClassLoader到底初始化了那些類庫:

  1. URL[] urLs = Launcher.getBootstrapClassPath().getURLs(); 
  2.        for (URL urL : urLs) { 
  3.            System.out.println(urL.toExternalForm()); 
  4.        } 

 JDK9 后

負責加載啟動時的基礎模塊類,比如:

  • java.base
  • java.management
  • java.xml

1.2 Platform ClassLoader

JDK8 時Extension ClassLoader

只有一個實例,由sun.misc.Launcher$ExtClassLoader實現:

  • 負責加載\lib\ext或java.ext.dirs系統變量指定的路徑中的所有類庫
  • 加載一些擴展的系統類,比如XML、加密、壓縮相關的功能類等

JDK9時替換為平臺類加載器

加載一些平臺相關的模塊,比如java.scripting、java.compiler*、 java.corba*。

那為何 9 時廢除替換了呢?

JDK8 的主要加載 jre lib 的ext,擴展 jar 包時使用,這樣操作并不推薦,所以廢除。而 JDK9 有了模塊化,更無需這種擴展加載器。

1.3 Application ClassLoader

只有一個實例,由sun.misc.Launcher$AppClassLoader實現。

JDK8 時

負責加載系統環境變量ClassPath或者系統屬性java.class.path指定目錄下的所有類庫。

如果應用程序中沒有定義自己的加載器,則該加載器也就是默認的類加載器。該加載器可以通過java.lang.ClassLoader.getSystemClassLoader獲取。

JDK9 后

應用程序類加載器,用于加載應用級別的模塊,比如:

  • jdk.compiler
  • jdk.jartool
  • jdk.jshell

  • classpath路徑中的所有類庫

第二、三層類加載器為Java語言實現,用戶也可以

1.4 自定義類加載器

用戶自定義的加載器,是java.lang.ClassLoader的子類,用戶可以定制類的加載方式;只不過自定義類加載器其加載的順序是在所有系統類加載器的最后。

1.5 Thread Context ClassLoader

每個線程都有一個類加載器(jdk 1.2后引入),稱之為Thread Context ClassLoader,如果線程創建時沒有設置,則默認從父線程中繼承一個,如果在應用全局內都沒有設置,則所有Thread Context ClassLoader為Application ClassLoader.可通過Thread.currentThread().setContextClassLoader(ClassLoader)來設置,通過Thread.currentThread().getContextClassLoader()來獲取.

線程上下文加載器有什么用?

該類加載器容許父類加載器通過子類加載器加載所需要的類庫,也就是打破了我們下文所說的雙親委派模型。

這有什么好處呢?

利用線程上下文加載器,我們能夠實現所有的代碼熱替換,熱部署,Android中的熱更新原理也是借鑒如此。

2 驗證類加載器

2.1 查看本地類加載器


在JDK8環境中,執行結果如下


AppClassLoader的Parent為Bootstrap,它是通過C/C++實現的,并不存在于JVM體系內,所以輸出為 null。

類加載器的特點

  • 類加載器并不需要等到某個類"首次主動使用”的時候才加載它,JVM規范允許類加載器在預料到某個類將要被使用的時候就預先加載它
  • Java程序不能直接引用啟動類加載器,直接設置classLoader為null,默認就使用啟動類加載器
  • 如果在加載的時候.class文件缺失,會在該類首次主動使用時通知LinkageError錯誤,如果一直沒有被使用,就不會報錯
  • 如果沒有指定父加載器,默認就是啟動加載器
  • 每個類加載器都有自己的命名空間,命名空間由該加載器及其所有父加載器所加載的類構成。不同的命名空間,可以出現類的全路徑名相同的情況
  • 運行時包由同一個類加載器的類構成,決定兩個類是否屬于同一個運行時包,不僅要看全路徑名是否一樣,還要看定義類加載器是否相同。只有屬于同一個運行時包的類才能實現相互包內可見

低層次的當前類加載器,不能覆蓋更高層次類加載器已經加載的類

如果低層次的類加載器想加載一個未知類,要非常禮貌地向上逐級詢問:“請問,這個類已經加載了嗎?”

被詢問的高層次類加載器會自問兩個問題

  • 我是否已加載過此類
  • 如果沒有,是否可以加載此類

只有當所有高層次類加載器在兩個問題的答案均為“否”時,才可以讓當前類加載器加載這個未知類

左側綠色箭頭向上逐級詢問是否已加載此類,直至Bootstrap ClassLoader,然后向下逐級嘗試是否能夠加載此類,如果都加載不了,則通知發起加載請求的當前類加載器,準予加載

在右側的三個小標簽里,列舉了此層類加載器主要加載的代表性類庫,事實上不止于此

通過如下代碼可以查看Bootstrap 所有已加載類庫


執行結果


Bootstrap加載的路徑可以追加,不建議修改或刪除原有加載路徑

在JVM中增加如下啟動參數,則能通過Class.forName正常讀取到指定類,說明此參數可以增加Bootstrap的類加載路徑:

  1. -Xbootclasspath/a:/Users/sss/book/ easyCoding/byJdk11/src 

如果想在啟動時觀察加載了哪個jar包中的哪個類,可以增加

  1. -XX:+TraceClassLoading 

此參數在解決類沖突時非常實用,畢竟不同的JVM環境對于加載類的順序并非是一致的

有時想觀察特定類的加載上下文,由于加載的類數量眾多,調試時很難捕捉到指定類的加載過程,這時可以使用條件斷點功能

比如,想查看HashMap的加載過程,在loadClass處打個斷點,并且在condition框內輸入如圖


JVM如何確立每個類在JVM的唯一性

類的全限定名和加載這個類的類加載器的ID

在學習了類加載器的實現機制后,知道雙親委派模型并非強制模型,用戶可以自定義類加載器,在什么情況下需要自定義類加載器呢?

  • 隔離加載類

           在某些框架內進行中間件與應用的模塊隔離,把類加載到不同的環境

           比如,阿里內某容器框架通過自定義類加載器確保應用中依賴的jar包不會影響到中間件運行時使用的jar包

  • 修改類加載方式

           類的加載模型并非強制,除Bootstrap外,其他的加載并非一定要引入,或者根據實際情況在某個時間點進行按需進行動態加載

  • 擴展加載源

           比如從數據庫、網絡,甚至是電視機機頂盒進行加載

  • 防止源碼泄露

           Java代碼容易被編譯和篡改,可以進行編譯加密。那么類加載器也需要自定義,還原加密的字節碼。

實現自定義類加載器的步驟

  • 繼承ClassLoader
  • 重寫findClass()方法
  • 調用defineClass()方法

一個簡單的類加載器實現的示例代碼如下


由于中間件一般都有自己的依賴jar包,在同一個工程內引用多個框架時,往往被迫進行類的仲裁。按某種規則jar包的版本被統一指定, 導致某些類存在包路徑、類名相同的情況,就會引起類沖突,導致應用程序出現異常。

主流的容器類框架都會自定義類加載器,實現不同中間件之間的類隔離,有效避免了類沖突。

 

責任編輯:姜華 來源: JavaEdge
相關推薦

2021-01-29 06:06:12

JDK15類加載Java

2021-01-29 06:08:33

JDK15Java

2020-09-17 08:09:16

JDK發布預覽

2009-07-07 16:10:02

JDK最新版本JDK安裝JDK下載

2009-12-16 10:04:51

Chrome瀏覽器漏洞

2024-04-09 08:41:41

JVM類加載Java

2010-06-08 10:15:45

opensuse 11

2025-04-14 02:25:00

2020-10-26 11:20:04

jvm類加載Java

2023-08-02 08:38:27

JVM加載機制

2013-08-26 17:17:37

Ubuntu 12.0

2023-11-19 19:01:53

UbuntuCalibre

2012-02-15 09:37:38

Firefox

2009-05-27 08:56:49

IQ瀏覽器瀏覽器新功能

2021-07-05 06:51:43

Java機制類加載器

2024-03-12 07:44:53

JVM雙親委托機制類加載器

2009-09-10 09:06:06

思科CCNP認證教材思科CCNP認證

2009-04-03 08:43:57

2009-04-06 08:22:57

2009-12-31 11:09:36

Ubuntu wine
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久久久久久久久久久午夜片 | 精品国产青草久久久久福利 | 欧美视频在线看 | 精品欧美激情在线观看 | 国产激情91久久精品导航 | 亚洲不卡视频 | 欧美一区二区三区视频 | 精精国产xxxx视频在线播放 | 亚洲精品在线看 | 黑人巨大精品 | 色综合中文 | 一级黄色毛片免费 | 中文字幕亚洲一区二区三区 | 国产精品成人久久久久 | www.黄色在线观看 | 久久成 | 中文字幕在线观看视频网站 | 久久国产精品视频 | 亚洲国产精品一区 | 欧美亚洲激情 | 欧美一区二区小视频 | 99在线免费观看视频 | 国产一区二区三区四区三区四 | 天天操天天射综合 | 欧美精品网站 | 久久综合一区 | 欧美日韩成人在线 | 天天av天天好逼 | 91精品国产综合久久婷婷香蕉 | 久久久一区二区三区四区 | 罗宾被扒开腿做同人网站 | 91精品国产色综合久久 | av中文字幕网 | 亚洲精品99 | 久久精品成人 | 精品国产欧美日韩不卡在线观看 | 一区二区三区高清在线观看 | 亚洲国产黄色av | 日韩高清一区 | 99热这里只有精品8 激情毛片 | 国产日韩欧美精品一区二区 |