JVM類加載器面試題及原理

JVM只會運行二進制文件,類加載器的作用就是將字節碼文件加載到JVM中,從而讓Java程序能夠啟動起來。

1. 類加載器的種類

  • 啟動類加載器(BootStrap ClassLoader):加載JAVA_HOME/jre/lib目錄下的庫
  • 擴展類加載器(ExtClassLoader):主要加載JAVA_HOME/jre/lib/ext目錄中的類
  • 應用類加載器(AppClassLoader):用于加載classPath下的類
  • 自定義類加載器(CustomizeClassLoader):自定義類繼承ClassLoader,實現自定義類加載規則。
    在這里插入圖片描述

2. 雙親委派模型

2.1 原理

加載某一個類,先委托上一級的加載器進行加載,如果上級加載器也有上級,則會繼續向上委托,如果該類委托上級沒有被加載,子加載器嘗試加載該類

  • student類在應用類加載器,向上委托,但lib和ext目錄都沒有student,所以向下由含有student類的子加載器(應用類加載器)加載student類
  • string類在應用類加載器,向上委托,lib目錄下有,于是加載string類然后返回給應用類加載器讓它直接使用
    在這里插入圖片描述

2.2 使用場景

JVM為什么采用雙親委派機制?

  1. 通過雙親委派機制可以避免某一個類被重復加載,當父類已經加載后則無需重復加載,保證唯一性
  2. 為了安全,保證類庫API不會被修改
    ex:
package java.long;
public class String{public static void main (Stringll args) {System.out.println("demo info");}
}

此時執行main函數,會出現異常,在類java.lang.String 中找不到 main 方法

錯誤:在類 java.Lang.string 中找不到 main 方法,請將 main 方法定義為:
public static void main(String[] args)
否則 JavaFX 應用程序類必須擴展
javafx.application.Application

報錯原因:由于是雙親委派的機制,javalang.String的在啟動類加載器得到加載,因為在核心jre庫中有其相同名字的類文件,但該類中并沒有main方法。這樣就能防止惡意篡改核心API庫。(所以這就是為什么類名不能是關鍵字的根本原因)

3. 類裝載的執行過程

  • 類從加載到虛擬機中開始,直到卸載 止,它的整個生命周期包括了:加載、驗證、準備、解析、初始化、使用和卸載這7個階段。
  • 其中,驗證、準備和解析這三個部分統稱為連接(linking)
    在這里插入圖片描述

3.1 加載階段

查找和導入class文件

  • 通過類的全名,獲取類的二進制數據流。
  • 解析類的二進制數據流為方法區內的數據結構(Java類模型)
  • 創建java.lang.Class類的實例,表示該類型。作為方法區這個類的各種數據的訪問入口
    在這里插入圖片描述

3.2 連接階段

3.2.1 驗證階段

保證加載類的準確性
驗證類是否符合JVM規范,安全性檢查

  • 格式檢查,如:文件格式是否錯誤、語法是否錯誤、字節碼是否合規(1)(2)(3)
    1. 文件格式驗證
    2. 元數據驗證
    3. 字節碼驗證
  • Class文件在其常量池會通過字符串記錄自己將要使用的其他類或者方法,檢查它們是否存在(4)
    4. 符號引用驗證
    在這里插入圖片描述

3.2.2 準備階段

內類變量分配內存并設置類變量初始值

  1. static變量,分配空間在準備階段完成(設置默認值),賦值在初始化階段完成
  2. static變量是final的基本類型,以及字符串常量,值已確定,賦值在準備階段完成
  3. static變量是final的引用類型,那么賦值也會在初始化階段完成
public class Application {static int b = 10;      //(1)static final int c = 20;   //(2)static final String d = "hello";   //(2)static final Object obj = new Object;  //(3)

3.2.3 解析階段

把類中的符號引用轉換為直接引用
比如:方法中調用了其他方法,方法名可以理解為符號引用,而直接引用就是使用指針直接指向方法

  • 符號引用:代#的是符號引用,符號引用可能也引用其他符號引用或直接引用類
  • 直接引用:找到符號指的類與方法去執行
    在這里插入圖片描述

在這里插入圖片描述

3.3 初始化階段

對類的靜態變量,靜態代碼塊執行初始化操作

  • 如果初始化一個類的時候,其父類尚未初始化,則優先初始化其父類。
  • 如果同時包含多個靜態變量和靜態代碼塊,則按照自上而下的順序依次執行。
//Animal是Cat父類
//子類初始化,如果父類還沒初始化,會引發父類先初始化
System.out.println(Cat.sex);
//子類訪問父類靜態變量,只觸發父類初始化
System.out.println(Cat.num);

3.4 使用階段

JVM 開始從入口方法開始執行用戶的程序代碼

  • 調用靜態類成員信息(比如:靜態字段、靜態方法)
  • 使用new關鍵字為其創建對象實例

3.5 卸載階段

當用戶程序代碼執行完畢后,JVM便開始銷毀創建的Class對象。

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

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

相關文章

C語言每日一練——day_3(快速上手C語言)

引言 針對初學者,每日練習幾個題,快速上手C語言。第三天。(會連續更新) 采用在線OJ的形式 什么是在線OJ? 在線判題系統(英語:Online Judge,縮寫OJ)是一種在編程競賽中用…

用Qt手搓AI助手,挑戰24小時開發DeepSeek Assistant!

一、項目需求分析與技術選型 DeepSeekAssistant是一款基于深度求索(DeepSeek)API的智能對話助手,核心需求包括: 用戶界面友好:支持多輪對話展示數據持久化:歷史記錄存儲與檢索異步網絡通信:AP…

Linux 環境變量快速上手指南

Linux 環境變量快速上手 1. 什么是環境變量 環境變量(Environment Variables)是操作系統中用于存儲配置信息的一種機制,可以在運行時被進程讀取和使用。常見環境變量示例: PATH: 存放可執行文件搜索路徑。HOME: 當前用戶的家目錄…

萬字技術指南STM32F103C8T6 + ESP8266-01 連接 OneNet 平臺 MQTT/HTTP

此博客為一份詳細的指南,涵蓋 STM32F103C8T6 通過 ESP8266-01 連接 OneNet 平臺,并使用 MQTT/HTTP 進行數據通信的完整流程。這份文檔包括: OneNet 平臺的介紹與功能概覽在 OneNet 上創建和配置設備的方法STM32CubeIDE 的開發環境搭建ESP826…

Go本地緩存設計與實現

本地緩存是一個項目中很常見的組件。在很多人的眼中就是一個簡單的key-value的map存儲即可實現,但實際上,設計一個本地緩存需要考慮的問題遠比你想象的多,比如說,本地緩存是將數據存儲在內存,若數據量激增突破了內存限…

深入解析 JavaScript 原型與原型鏈:從原理到應用

原型和原型鏈是 JavaScript 中實現對象繼承和屬性查找的核心機制。為了更深入地理解它們,我們需要從底層原理、實現機制以及實際應用等多個角度進行分析。 1. 原型(Prototype) 1.1 什么是原型? 每個 JavaScript 對象&#xff08…

FPGA時序約束的幾種方法

一,時鐘約束 時鐘約束是最基本的一個約束,因為FPGA工具是不知道你要跑多高的頻率的,你必要要告訴工具你要跑的時鐘頻率。時鐘約束也就是經常看到的Fmax,因為Fmax是針對“最差勁路徑”,也就是說,如果該“最差勁路徑”得到好成績,那些不是最差勁的路徑的成績當然比…

Visual Studio Code打開遠程服務器項目,打開服務器Android上百G源碼,SSH免密連接方式

Visual Studio Code打開遠程服務器項目 1,Visual Studio Code拓展中,安裝遠程插件 Remote Development 2,SSH免密連接,A電腦免密連接B,配置B電腦.ssh/authorized_keys A電腦的.ssh/id_rsa.pub中的公鑰內容,…

AWS云編排詳解-Cloud Formation

作者:私語茶館 1.關鍵概念 名詞 說明 軟件: CloudFormation 描述AWS 資源、配置值和互連關系。借助集成設施即代碼加快云部署 CloudFormation Designer 拖拽式圖形化模板編輯界面。 Amazon Simple Notification Service (SNS) SNS可通過電子郵件跟蹤堆棧的創建和刪除進度,…

《PyQt5》——設計Python GUI(圖形用戶界面)實例

PyQt5 PyQt5的配置和基礎使用可以參考這篇文章:《 PyQt5》—— 創建 Python GUI(圖形用戶界面) Python GUI(圖形用戶界面)實例 本實例是設計一個通過玉米和豆粕的價格來預測生豬的價格,并顯示預測價格與實…

kali linux 打開 word

Kali Linux是一款專為網絡安全領域而設計的操作系統,它集成了大量的安全工具,幫助用戶進行網絡滲透測試和安全評估。作為一款功能強大的操作系統,Kali Linux可以滿足用戶在網絡安全領域的各種需求,包括滲透測試、漏洞分析、數字取…

hooks useModule自定義hooks (二次封裝AgGridReact ag-table)自定義表頭,自定義表頭搜索

場景業務: 多次運用AgGridReact的table 列表 思路: 運用自定義hooks進行二次封裝: 通用配置例如:傳參的參數,傳參的url,需要緩存的key這些鍵值類 定制化配置例如:需要對table 的一些定制化傳…

SpringBoot最簡單方式實現自定義異常頁面(404)

最簡單的方式實現所有自定義異常頁面(如 404、500 等)是通過 靜態資源文件 或 模板引擎 來實現。 方法 1:使用靜態資源文件(最簡單) Spring Boot 默認會在 src/main/resources/static 或 src/main/resources/public …

django下防御race condition漏洞(競爭型漏洞)

目錄 競爭型漏洞 概念 常見類型及示例 環境搭建 ?編輯漏洞復現 ucenter/1/ ucenter/2/ ucenter/3/ ucenter/4/ 總結 悲觀鎖 樂觀鎖 競爭型漏洞 概念 競爭型漏洞,也稱為競態條件漏洞(Race Condition Vulnerability),…

用Python寫一個算24點的小程序

一、運行界面 二、顯示答案——遞歸介紹 工作流程&#xff1a; 1. 基本情況&#xff1a;函數首先檢查輸入的數字列表 nums 的長度。如果列表中只剩下一個數字&#xff0c;它會判斷這個數字是否接近 24&#xff08;使用 abs(nums[0] - 24) < 1e-10 來處理浮點數精度問題&…

PostgreSQL 18新特性之虛擬生成列

PostgreSQL 12 提供了生成列&#xff08;GENERATED ALWAYS AS STORED&#xff09;功能&#xff0c;但是只能支持存儲型的生成列&#xff0c;需要占用存儲空間&#xff0c;更新成本高。 為此&#xff0c;PostgreSQL 18 即將引入一個新的增強&#xff1a;虛擬生成列。這種類型的…

GitHub上傳項目

總結&#xff08;有基礎的話直接執行這幾步&#xff0c;就不需要再往下看了&#xff09;&#xff1a; git init 修改git的config文件&#xff1a;添加:[user]:name你的github用戶名 email你注冊github的用戶名 git branch -m master main git remote add origin 你的URL gi…

常見排序算法深度評測:從原理到10萬級數據實戰

常見排序算法深度評測&#xff1a;從原理到10萬級數據實戰 摘要 本文系統解析冒泡排序、選擇排序、插入排序、希爾排序、歸并排序、快速排序、堆排序和基數排序8種經典算法&#xff0c;通過C語言實現10萬隨機數排序并統計耗時。測試顯示&#xff1a;快速排序綜合性能最優&…

動態規劃填表技巧:固定最后一個數 vs 固定倒數第二個數

在動態規劃中&#xff0c;填表時固定最后一個數還是倒數第二個數&#xff0c;取決于問題的定義和狀態轉移方程的設計。 目錄 1. 固定最后一個數 適用場景 特點 示例 2. 固定倒數第二個數 適用場景 特點 示例 3. 固定最后一個數與倒數第二個數的對比 4. 總結 1. 固定最…

【C】鏈式二叉樹算法題2

目錄 1 另一棵樹的子樹 1&#xff09; 題目描述 示例1&#xff1a; 示例2&#xff1a; 2&#xff09; 算法解析 3&#xff09; 代碼 2 二叉樹的遍歷 1&#xff09; 問題描述 2&#xff09; 算法解析 3&#xff09; 代碼 3 總結 1 另一棵樹的子樹 leetcode鏈接…