JVM 類加載器之間的層次關系,以及類加載的委托機制

JVM 類加載器之間存在一種層次關系,通常被稱為雙親委派模型 (Parent Delegation Model)。這種層次關系和委托機制是 Java 類加載機制的核心,對于保證 Java 程序的安全性和避免類沖突至關重要。

1. 類加載器的層次關系:

JVM 中的類加載器(ClassLoader)主要分為以下幾種,它們之間存在自頂向下的層次關系(父子關系,但不是繼承關系,而是組合關系):

  • 啟動類加載器 (Bootstrap Class Loader):

    • 最頂層的類加載器。
    • 負責加載 Java 核心類庫,例如 java.langjava.utiljava.io 等包中的類(通常位于 <JAVA_HOME>/jre/lib 目錄下的 rt.jarresources.jar 等)。
    • 用 C/C++ 實現,是 JVM 的一部分,不是 Java 類。
    • 沒有父類加載器。
    • 無法通過 Java 代碼直接獲取到啟動類加載器。
  • 擴展類加載器 (Extension Class Loader):

    • 父類加載器是啟動類加載器。
    • 負責加載 Java 擴展類庫(通常位于 <JAVA_HOME>/jre/lib/ext 目錄下的 jar 包,或者由 java.ext.dirs 系統屬性指定的目錄)。
    • sun.misc.Launcher$ExtClassLoader 的實例(Java 類)。
  • 應用程序類加載器 (Application Class Loader / System Class Loader):

    • 父類加載器是擴展類加載器。
    • 負責加載應用程序的類(classpath 下的類,包括你寫的代碼、第三方庫等)。
    • sun.misc.Launcher$AppClassLoader 的實例(Java 類)。
    • 通常是默認的類加載器。 可以通過 ClassLoader.getSystemClassLoader() 獲取。
  • 自定義類加載器 (User-Defined Class Loader):

    • 父類加載器通常是應用程序類加載器(也可以是其他自定義類加載器)。
    • 由開發者自定義,繼承 java.lang.ClassLoader 類。
    • 用于實現特殊的類加載邏輯,例如:
      • 從網絡加載類。
      • 從數據庫加載類。
      • 對類進行加密和解密。
      • 實現熱部署(HotSwap)。
      • 實現模塊化(OSGi)。

類加載器層次關系圖示:

                     +-----------------------------+|  Bootstrap Class Loader     |  (C/C++)+-----------------------------+↑|  (Parent)|+-----------------------------+|  Extension Class Loader     |  (sun.misc.Launcher$ExtClassLoader)+-----------------------------+↑|  (Parent)|+-----------------------------+| Application Class Loader    |  (sun.misc.Launcher$AppClassLoader)+-----------------------------+↑|  (Parent)|+-----------------------------+|  User-Defined Class Loader  |  (extends java.lang.ClassLoader)+-----------------------------+

2. 雙親委派模型 (Parent Delegation Model):

  • 工作原理:

    1. 當一個類加載器需要加載類時,它首先不會自己嘗試加載,而是 委托給它的父類加載器 去加載。
    2. 父類加載器會檢查自己是否已經加載過該類。如果已經加載,則直接返回 Class 對象。
    3. 如果父類加載器沒有加載過該類,則會嘗試加載。如果父類加載器在其搜索范圍內找到了該類,則加載成功,并返回 Class 對象。
    4. 如果父類加載器無法加載該類(在其搜索范圍內找不到該類),則 將加載請求返回給子類加載器
    5. 子類加載器嘗試加載該類。如果子類加載器能夠加載,則加載成功,并返回 Class 對象。
    6. 如果子類加載器也無法加載該類,則拋出 ClassNotFoundException 異常。
  • 特例: 啟動類加載器沒有父類加載器,它會直接嘗試加載。

  • 代碼示例 (簡化版):

    // java.lang.ClassLoader 中的 loadClass 方法 (簡化版)
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {// 1. 檢查該類是否已經被加載過Class<?> c = findLoadedClass(name);if (c == null) {try {// 2. 如果有父類加載器,則委托給父類加載器加載if (parent != null) {c = parent.loadClass(name, false);} else {// 3. 如果沒有父類加載器 (到達了啟動類加載器),則調用 findBootstrapClassOrNullc = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// 父類加載器無法加載該類}if (c == null) {// 4. 如果父類加載器無法加載,則調用 findClass 方法嘗試自己加載c = findClass(name);}}if (resolve) {resolveClass(c); // 鏈接類 (可選)}return c;}
    }
    
    • findClass() 方法是需要子類加載器重寫的方法, 用于實現自定義的類加載邏輯.

3. 雙親委派模型的優點:

  • 避免類的重復加載: 同一個類只會被加載一次,避免了命名沖突和資源浪費。
  • 保證 Java 核心類庫的安全性: 用戶自定義的類加載器無法加載或替換 Java 核心類庫中的類(例如 java.lang.Objectjava.lang.String),因為核心類庫總是由啟動類加載器加載。這可以防止惡意代碼篡改核心類庫,破壞 JVM 的安全性。
  • 命名空間隔離: 不同的類加載器加載的類位于不同的命名空間, 可以防止類名沖突.

4. 破壞雙親委派模型:

雖然雙親委派模型有很多優點,但在某些情況下,可能需要破壞雙親委派模型,例如:

  • JDBC、JNDI、JAXP 等 SPI (Service Provider Interface) 機制:

    • 這些 API 的核心接口是由啟動類加載器加載的,但具體的實現類通常由應用程序類加載器或自定義類加載器加載。
    • 為了解決這個問題,Java 引入了線程上下文類加載器 (Thread Context ClassLoader)。
    • 可以通過 Thread.currentThread().getContextClassLoader() 獲取線程上下文類加載器。
    • 例如,JDBC 驅動程序通常由應用程序類加載器加載,但 JDBC API (如 java.sql.DriverManager) 需要能夠加載這些驅動程序。DriverManager 會使用線程上下文類加載器來加載驅動程序。
  • OSGi (Open Service Gateway initiative):

    • OSGi 是一個模塊化系統,每個模塊(bundle)都有自己的類加載器。
    • OSGi 的類加載器模型不是嚴格的雙親委派模型,而是更復雜的網狀結構。
  • 熱部署 (HotSwap):

    • 在應用程序運行時,動態地替換或更新類。
    • 通常需要自定義類加載器,并破壞雙親委派模型。
  • Tomcat:

    • Tomcat 為了實現 web 應用之間的隔離,以及共享庫的加載,破壞了雙親委派模型。
    • 每個 web 應用都有自己的類加載器 (WebAppClassLoader)。

總結:

JVM 類加載器之間存在層次關系(啟動類加載器、擴展類加載器、應用程序類加載器、自定義類加載器),并通過雙親委派模型協同工作。雙親委派模型保證了類加載的順序和安全性,避免了類的重復加載,并防止了核心類庫被篡改。 在某些特殊情況下,可能需要破壞雙親委派模型(例如,SPI、OSGi、熱部署)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/73200.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/73200.shtml
英文地址,請注明出處:http://en.pswp.cn/web/73200.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于 Vue 3 的PDF和Excel導出

以下是基于 Vue 3 Composition API 的完整實現&#xff0c;包括 PDF 和 Excel 導出。 一、PDF 導出 (Vue 3) 安裝依賴 在項目中安裝相關庫&#xff1a; npm install html2canvas jspdf Vue 3 代碼實現 <template><div><div ref"pdfContent" cla…

【Jupyter】notebook無法顯示tqdm進度條

錯誤描述 from tqdm.notebook import tqdm 用的時候報錯&#xff1a; Error displaying widget解決方式 # 先裝nodejs conda install -c conda-forge nodejs20# 重裝ipywidgets pip uninstall ipywidgets pip install ipywidgets jupyter labextension install jupyter-wid…

ubuntu20如何升級nginx到最新版本(其它版本大概率也可以)

前言&#xff1a; Nginx非常常用&#xff0c;所以在網絡安全方面備受“關注”。其漏洞非常多&#xff0c;要經常保持軟件更新版本才能更好的保證安全。但是Ubuntu官網適配nginx非常慢&#xff0c;所以nginx官方也會推出針對主流Linux操作系統的包管理工具安裝方式。 步驟&…

word插入Mathtype公式居中和自動更新

word插入公式自動更新 前提&#xff1a;安裝Mathtype 1.word中查看頁的寬度 出現如下 2.設置樣式 出現這個窗口 給樣式隨便起個名字 3.修改樣式 3.1 設置兩個制表位 第二個 3.2 修改公式字體 如下所示 4. 修改公式格式 4.1在word中打開 Mathtype 4.2 修改公式的格式 變成…

如何從后端實現頁面跳轉?

例&#xff1a;請求轉發 例&#xff1a;重定向 例&#xff1a;區別&#xff1a;攜帶參數的后端跳轉 例&#xff1a;是否可以訪問外部資源 請求轉發&#xff1a;客戶端發起一個請求到服務端&#xff0c;服務端把這個請求轉發至其他地方 重定向&#xff1a;客戶端發起一個請求…

APIJSON快速入門

作者 版本 時間 內容 備注 Allen V1.0.0 2021/08/19 初稿完成 AllenV1.0.1 2021/08/22 添加常見問題 1.流程說明 一個接口的開發,比如Java用SpringBoot,Mybatis來開發一般來說就像下面這個流程 部署上這個項目后,流程變成了這樣 如果使用 apijson-framework,還可進一步簡化…

STM32八股【3】------RAM和片上FLASH

1、RAM和FLASH構成 1.RAM ┌──────────────────────────┐ │ 棧區 (Stack) │ ← 從RAM頂端向下擴展&#xff08;存儲局部變量、函數調用信息&#xff09; │--------------------------│ │ 堆區 (Heap) │ ← …

基于springboot的星之語明星周邊產品銷售網站(050)

摘要 隨著信息互聯網信息的飛速發展&#xff0c;無紙化作業變成了一種趨勢&#xff0c;針對這個問題開發一個專門適應洗衣店業務新的交流形式的網站。本文介紹了星之語明星周邊產品銷售網站的開發全過程。通過分析企業對于星之語明星周邊產品銷售網站的需求&#xff0c;創建了一…

Android Launcher3 HotSeat文件夾創建禁止方案全解析

一、技術背景與實現原理 在Android 13 Launcher3定制開發中&#xff0c;需屏蔽HotSeat區域的文件夾創建功能。該功能涉及的核心事件處理流程如下&#xff1a; 復制 [拖拽事件] -> [Workspace.onDrop()] -> [CellLayout.performReorder()]└─> [createUserFolderIf…

從零到一開發一款 DeepSeek 聊天機器人

AI聊天機器人 目標設計方案系統架構技術選型功能模塊 實現代碼環境配置安裝依賴 核心代碼API 請求函數主循環函數 功能擴展1. 情感分析2. 多語言支持3. 上下文記憶4. 用戶身份識別 總結附錄 目標 開發一個智能聊天機器人&#xff0c;旨在為用戶提供自然、流暢的對話體驗。通過…

OpenCV-Contrib常用擴展模塊

?一、高頻使用模塊? ?aruco 模塊? ?功能?&#xff1a;用于生成與檢測二維碼&#xff08;如 ArUco Marker、AprilTag&#xff09;&#xff0c;支持增強現實&#xff08;AR&#xff09;中的物體定位與姿態估計?。?典型應用?&#xff1a;AR 應用中的場景錨定、機器人導航…

pfsense部署三(snort各版塊使用)

在上篇文章上我們已經進行了snort的基礎配置了&#xff0c;接下來需要進行snort的具體配置&#xff0c;其中包括各板塊的設置&#xff0c;例&#xff1a;白名單&#xff0c;警報&#xff0c;規則設置等 規則庫配置 點擊 service > snort > Global Settings ,在code值…

汽車制造MES

一、整體生產工序 整車的車間主要分為4個部分&#xff1a;沖壓、焊裝、涂裝、總裝、整車入庫 系統架構 二、車間概括 1.沖壓車間 2.焊裝車間 3.涂裝車間 4.總裝車間 1.整車裝配的部件都要可追溯、數據實時性要求高、涉及分裝與總裝的協調、物流配送的協調、質量批處理的協調、…

python接口自動化pytest+request+allure

自己自學接口自動化過程遇到的問題及解決方法記錄 首先是一個簡單的請求 import requests#這是一個簡單是get請求 def test_get():geturl https://so.csdn.net/api/v1/relevant-search?querypycharm%E5%AE%89%E8%A3%85requests%E5%BA%93&platformpcgetr requests.get(…

CompletableFuture的使用

CompletableFuture 是 Java 8 引入的異步編程工具&#xff0c;通過鏈式調用和非阻塞操作簡化多線程任務編排。 創建異步任務 1.帶返回值的任務 CompletableFuture<String> future CompletableFuture.supplyAsync(() -> "Hello");2. ?無返回值的任務 使…

GLB文件介紹

GLB文件是由支持glTF&#xff08;GL Transmission Format&#xff09;標準的軟件或工具生成的。glTF是一種開放的3D模型傳輸格式&#xff0c;而GLB是其二進制版本&#xff0c;通常用于嵌入紋理和模型數據。以下是常見的生成GLB文件的軟件和工具&#xff1a; 1. 3D建模軟件 ? …

計算機網絡的分類及其性能指標

一. 計算機網絡的分類 1. 按分布范圍分類 廣域網&#xff08;WAN&#xff09; 也稱遠程網。廣域網提供長距離通信&#xff0c;通常是幾十千米到幾千千米的區域&#xff0c;比如跨國通信。連接廣域網的各結點交換機的鏈路一般是高速鏈路&#xff0c;具有較大的通信容量城域網&…

gralloc usage flags

下面這些示例主要說明了 gralloc usage flags 在圖像處理和多媒體應用中如何影響性能和正確性。讓我們逐個詳細分析每個問題的 根因 和 修復方案&#xff0c;并深入解析 gralloc 標志對 緩存管理 和 數據流 的影響。 ? Example 1: 長曝光快照耗時異常 &#x1f4cc; 問題描述…

關于kafka的一些知識總結

Kafka 1. 基本知識 1.1 前置知識 topic表示一個類型/業務的數據的組為方便擴展&#xff0c;提高吞吐率&#xff0c;一個topic分為多個partition。配合分區的設計&#xff0c;提出消費者組的概念&#xff0c;每個消費者并行消費&#xff0c;同時&#xff0c;一個分區的數據&a…

深入理解traceroute命令及其原理

traceroute 是一個網絡診斷工具&#xff08;Windows上叫tracert&#xff09;&#xff0c;用于顯示數據包從本地主機到遠程主機經過的路由&#xff08;跳數&#xff09;。它可以幫助您了解數據包在網絡中的傳輸路徑&#xff0c;以及每跳的延遲情況。這對于網絡故障排除、分析網絡…