JVM 類加載器 詳解

類加載器

兩個類來源于同一個 Class文件,被同一個Java虛擬機加載,只要加載它們的類加載器不同,那這兩個類就必定不相等

這里所指的“相等”,包括代表類的Class對象的equals()方法、isAssignableFrom()方法、isInstance()方法的返回結果,也包括了使用instanceof關鍵字做對象所屬關系判定等各種情況

總結:

類加載器

? 類加載器作用于類加載的加載階段,也就是加載class文件到方法區中,并且在方法區生成Class對象,通過Class對象可以訪問方法區中的類信息。每個Class對象都有一個引用指向加載它的類加載器。

? JVM中內置了三個類加載器,啟動類加載器、擴展類加載器、應用程序類加載器。其中,啟動類加載器用來加載JAVA_HOME/lib下的核心類庫比如rt.jar;擴展類加載器用來加載JAVA_HOME/lib/ext下的類;應用程序類加載器用來加載classpath下的類。

? 這三個類加載器都繼承自ClassLoad抽象類,類加載器可以通過getParent()方法來獲取它的父加載器,例如應用程序類加載器的父加載器是擴展類加載器,而擴展類加載器的父加載器是啟動類加載器,只不過擴展類加載器通過getParent()方法獲得的是null,因為啟動類加載器是基于c++實現的。

? 三個加載器的父子關系不是通過繼承來實現的,而是通過組合方式來實現的。

雙親委派模型:

  • 啟動類加載器(Bootstrap Class Loader):是由Hotspot虛擬機提供的類加載器,JDK9之前使用C++編寫的、JDK9之后使用Java編寫。默認加載Java安裝目錄/jre/lib下的類文件,比如rt.jar,tools.jar,resources.jar等。
  • 擴展類加載器(Extension Class Loader):默認加載Java安裝目錄/jre/lib/ext下的類文件。(JDK9及以后,被重命名為平臺類加載器Platform ClassLoader)
  • 應用程序類加載器(Application Class Loader):負責加載用戶類路徑(ClassPath)上所有的類庫

雙親委派機制指的是:自底向上查找是否加載過,再由頂向下進行加載

? 雙親委派模型:除了頂層的啟動類加載器外,其余的類加載器都應有自己的父類加載器。不過這里類加載器之間的父子關系一般不是以繼承(Inheritance)的關系來實現的,而是通常使用組合 (Composition)關系來復用父加載器的代碼。

在這里插入圖片描述

? 如果一個類加載器收到了類加載的請求,每個類加載器都會先檢查是否已經加載了該類,如果已經加載則直接返回,否則會將加載請求委派給父類加載器。每一個層次的類加載器都是如此,因此所有的加載請求最終都應該傳送到最頂層的啟動類加載器中,只有當父加載器反饋自己無法完成這個加載請求(它的搜索范圍中沒有找到所需的類)時, 子加載器才會嘗試自己去完成加載。

為什么使用雙親委派:

? 1.保證類加載的安全性,通過雙親委派機制避免惡意代碼替換JDK中的核心類庫,比如java.lang.String,確保核心類庫的完整性和安全性。

? 2.避免重復加載,雙親委派機制可以避免同一個類被多次加載。

為什么要向上委派,不能向下委派?

? 是否能一開始就由啟動類加載器加載所有的類,啟動類加載器發現不在自己加載范圍內的類就交給自己的子類加載器?答案是不行的,因為一個類加載器可以只有一個父類加載器,需要加載類時直接向上委派就行,但如果是向下委派,同時又有多個子類加載器,這時候就不知道要委派給哪個子類加載器的(可能有多個子類加載器的原因是因為可以有自定義類加載器,加載器的組合是多樣的,但不管怎樣,只可能有一個父類加載器),這就好比一個二叉樹,從葉子節點向上走,是有且只有一條唯一的路徑的,而且這條路徑的終點必然是根節點,而從根節點出發,一直向下走,是不能確定一條唯一路徑的,雖然最終能到達某一葉子節點,但具體是哪個葉子節點取決于每次向下走的路線決策。而且向下委派意味著需要修改應用程序類加載器的源碼。
在這里插入圖片描述

破壞雙親委派模型:

在這里插入圖片描述

自定義加載器的話,需要繼承 ClassLoader 。如果我們不想打破雙親委派模型,就重寫 ClassLoader 類中的 findClass() 方法即可,無法被父類加載器加載的類最終會通過這個方法被加載。但是,如果想打破雙親委派模型則需要重寫 loadClass() 方法。

Tomcat采用自定義類加載器破壞了雙親委派,實現了Web應用之間的類的隔離
在這里插入圖片描述
在這里插入圖片描述

JDBC:

? JDBC中使用了DriverManager來管理項目中引入的不同數據庫的驅動,比如mysql驅動、oracle驅動。

? DriverManager屬于rt.jar是啟動類加載器加載的。而用戶jar包中的驅動需要由應用類加載器加載,這就違反了雙親委派機制。

? DriverManage使用SPI機制,最終加載jar包中對應的驅動類。

? SPI中使用了線程上下文中保存的類加載器進行類的加載,這個類加載器一般是應用程序類加載器。

? 這種由啟動類加載器加載的類,委派應用程序類加載器去加載類的方式,打破了雙親委派機制。

? JDBC接口是jre下的,但實現是第三方供應商提供的,按理來說,一個類及其依賴類由同一個類加載器加載(確保這些類之間的依賴關系正確并保持一致),但這種情況下不會被同一個類加載器加載,這就需要用到線程上下文類加載器解決

? 線程上下文類加載器:當一個線程啟動時,jvm會將應用類加載器賦值給當前線程的線程上下文類加載器,此時父類加載器就可以提高線程上下文類加載器獲取到子類加載器,再由子類加載器加載父類找不到的類

在這里插入圖片描述

什么時候需要自定義類加載器:

  • 想加載非classpath隨意路徑的類文件
  • 隔離同名類,需要不同應用下的同名類可以不沖突,如tomcat容器

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

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

相關文章

Javascript 編程基礎(5)面向對象 | 5.1、構造函數實例化對象

文章目錄 一、構造函數實例化對象1、基本語法2、構造函數與原型的關系3、完整的原型鏈4、構造函數的特點5、prototype與__proto__屬性5.1、對象實例的__proto__屬性5.2、prototype屬性僅存在于函數對象5.3、實例與原型的關系5.4、獲取對象原型 6、注意事項 前言: 在…

自動駕駛科普(百度Apollo)學習筆記

1. 寫在前面 在過去的幾年里,自動駕駛技術取得飛速發展,人類社會正逐漸走向一個新時代,這個時代中,汽車不僅僅是一個交通工具,更是一個智能的、能夠感知環境、做出決策并自主導航的機器伙伴。現在正好也從事這塊的工作…

Windows應用-音視頻捕獲

下載“Windows應用-音視頻捕獲”項目 本應用可以同時捕獲4個視頻源和4個音頻源,可以監視視頻源圖像,監聽音頻源;可以將視頻源圖像寫入MP4文件,將音頻源寫入MP3或WAV文件;還可以錄制系統播放的聲音。本應用使用MFC對話框…

MATLAB生成大規模無線通信網絡拓撲(任意節點數量)

功能: 生成任意節點數量的網絡拓撲,符合現實世界節點空間分布和連接規律 效果: 30節點: 100節點: 500節點: 程序: %創建時間:2025年6月8日 %zhouzhichao %自然生長出n節點的網絡% …

TDengine 開發指南—— UDF函數

UDF 簡介 在某些應用場景中,應用邏輯需要的查詢功能無法直接使用內置函數來實現,TDengine 允許編寫用戶自定義函數(UDF),以便解決特殊應用場景中的使用需求。UDF 在集群中注冊成功后,可以像系統內置函數一…

C#提取CAN ASC文件時間戳:實現與性能優化

C#提取CAN ASC文件時間戳:實現與性能優化 在汽車電子和工業控制領域,CAN總線是最常用的通信協議之一。而ASC(ASCII)文件作為CAN總線數據的標準日志格式,廣泛應用于數據記錄和分析場景。本文將深入探討如何高效地從CAN…

計算機網絡基礎總結:TCP/IP 模型、TCP vs UDP、DNS 查詢過程

在學習計算機網絡的過程中,理解 TCP/IP 模型與 OSI 模型的對應關系、掌握 TCP 與 UDP 的區別,以及熟悉 DNS 的查詢過程,是打好網絡基礎的關鍵。本文將圍繞這三部分進行簡明扼要的講解。 一、TCP/IP 模型與 OSI 七層模型的對應關系 1. OSI 七…

基于PHP的扎染文創產品商城

有需要請加文章底部Q哦 可遠程調試 基于PHP的扎染文創產品商城 一 介紹 扎染文創產品商城系統基于原生PHP開發,數據庫mysql,前端bootstrap,jquery.js等。系統角色分為用戶和管理員。 技術棧:phpmysqlbootstrapphpstudyvscode 二…

數據庫學習(三)——MySQL鎖

一、MySQL鎖 當多個用戶或進程并發操作數據庫時,為了避免數據沖突、臟讀、不可重復讀、幻讀等問題,數據庫通過鎖機制來保證數據的一致性和完整性。 MySQL 鎖的總體分類: 分類維度類型說明按作用對象表級鎖(Table Lock&#xff…

<3>-MySQL表的操作

目錄 一,創建表 二,查看表結構 三,修改表 四,刪除表 一,創建表 語法: CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校驗規則 eng…

【OSG學習筆記】Day 15: 路徑動畫與相機漫游

本章來學習下漫游相機。 路徑動畫與相機漫游 本屆內容比較簡單,其實就是實現物體的運動和相機的運動 當然這兩個要一起執行。 貝塞爾曲線 貝塞爾曲線(Bzier curve)是一種在計算機圖形學、動畫制作、工業設計等領域廣泛應用的參數曲線&am…

LabVIEW自感現象遠程實驗平臺

LabVIEW開發自感現象遠程實驗平臺,通過整合 NI數據采集設備、菲尼克斯(Phoenix Contact)繼電器模塊及羅技(Logitech)高清攝像頭,實現遠程數據采集、儀器控制與實時監控三大核心功能。平臺突破傳統實驗裝置局…

數據結構——F/圖

一、圖的基本概念 圖是由頂點集合及頂點間的關系組成的一種數據結構&#xff1a;G (V&#xff0c; E)&#xff0c;其中&#xff1a; 頂點集合V {x|x屬于某個數據對象集}是有窮非空集合&#xff1b; E {(x,y)|x,y屬于V}或者E {<x, y>|x,y屬于V && Path(x, y)…

springcloud openfeign 偶現 Caused by: java.net.UnknownHostException

背景 最近查看日志發現某服務偶現Caused by: java.net.UnknownHostException 同時查看eureka的access.log 出現如下異常 10.xxx.xxx.xxx - - [27/May/2025:23:57:29 0800] “PUT /eureka/apps/{appName}/{host}:xxx-job:8082?statusUP&lastDirtyTimestamp1748351637173 H…

第12篇:數據庫中間件日志設計與追蹤系統落地實踐

12.1 引言&#xff1a;中間件日志系統為何如此關鍵&#xff1f; 數據庫中間件作為連接前端應用與后端數據庫的“網關”&#xff0c;承載著路由、負載均衡、SQL 改寫、權限控制等復雜邏輯。 在出現 性能問題、故障排查、安全審計 等場景中&#xff0c;若沒有完善的日志體系&am…

OpenAI對抗法庭命令:捍衛ChatGPT用戶隱私之戰

人工智能公司OpenAI近期正積極對抗一項涉及隱私問題的法庭命令。該命令要求OpenAI保留所有ChatGPT用戶日志&#xff0c;包括已刪除的對話記錄以及通過API調用生成的聊天內容。 命令背后的真實動機 值得注意的是&#xff0c;法院發布這一指令并非出于對用戶隱私或內容安全的考…

嵌入式學習--江協stm32day5

USART 1. 引腳與接口層 異步引腳&#xff1a; TX&#xff1a;發送數據輸出&#xff1b;RX&#xff1a;接收數據輸入&#xff1b;SW_RX&#xff1a;單線半雙工模式的接收引腳&#xff08;替代 RX&#xff09;。 同步引腳&#xff1a;SCLK&#xff1a;同步模式下的時鐘輸出&…

使用Fiddler抓包

有時候需要跟蹤一些小程序的HTTP請求&#xff0c;但是無法像瀏覽器一樣F12查看請求&#xff0c;因此需要借助其他的工具進行&#xff0c;在這里推薦使用Fiddler 配置 此時檢查系統代理已經變成如下配置&#xff1a; 抓包 此時隨便打開一個小程序&#xff0c;就可以進行抓包…

python學習打卡day47

DAY 47 注意力熱圖可視化 昨天代碼中注意力熱圖的部分順移至今天 知識點回顧&#xff1a; 熱力圖 作業&#xff1a;對比不同卷積層熱圖可視化的結果 # 可視化空間注意力熱力圖&#xff08;顯示模型關注的圖像區域&#xff09; def visualize_attention_map(model, test_loader,…

MySQL-運維篇

運維篇 日志 錯誤日志 錯誤日志是 MySQL 中最重要的日志之一&#xff0c;它記錄了當 mysqld 啟動和停止時&#xff0c;以及服務器在運行過程中發生任何嚴重錯誤時的相關信息當數據庫出現任何故障導致無法正常使用時&#xff0c;建議首先查看此日志。 該日志是默認開啟的&am…