jvm虛擬機筆記<三> 類文件結構與類載入機制

来源:https://www.cnblogs.com/lvoooop/archive/2019/12/04/11985086.html
-Advertisement-
Play Games

java虛擬機具有語言無關係,它只和“class文件“這種特定的二進位文件格式綁定。 不同語言的編譯器將對應的程式編譯成位元組碼文件(*.class),送給jvm執行。 2.1、魔數(是否可以被虛擬機執行)和class文件版本 2.2、常量池 2.3、訪問標誌(識別訪問信息) 2.4、類索引、父類索引 ...


java虛擬機具有語言無關係,它只和“class文件“這種特定的二進位文件格式綁定。

不同語言的編譯器將對應的程式編譯成位元組碼文件(*.class),送給jvm執行。

  • 2.1、魔數(是否可以被虛擬機執行)和class文件版本
  • 2.2、常量池
  • 2.3、訪問標誌(識別訪問信息)
  • 2.4、類索引、父類索引和介面索引集合
  • 2.5、欄位表集合
  • 2.6、方法表集合

————————————————————————————————————————————————

一.類載入時機:

共5種情形為主動引用,有且僅有此5種會觸發初始化,其他方式全部為被動引用,不會觸發類的初始化

5種情形:

  • 遇到new (實例化對象),getstatic(讀取一個類的靜態欄位) ,putstatic(設置一個類的靜態欄位), invokestatic(調用一個類的靜態方法)這4條指令,若類之前沒有初始化,需要先對其進行初始化。
  • 使用 java.lang.reflect包的方法對類進行反射調用時,若類之前沒有初始化,需要先對其進行初始化。
  • 當初始化一個類,其父類之前沒有初始化,需要先對其父類進行初始化。
  • 當虛擬機啟動時,主類會先被初始化(包含main方法的類)。
  • 使用jdk7的動態語言支持時,如果一個解析結果與靜態欄位或靜態方法有關,所對應的類之前沒有初始化,需要先對其進行初始化。

二.類載入過程

 

 其中類載入的過程包括了載入、驗證、準備、解析、初始化五個階段。

在這五個階段中,載入、驗證、準備和初始化這四個階段發生的順序是確定的,而解析階段則不一定,它在某些情況下可以在初始化階段之後開始,這是為了支持Java語言的運行時綁定(動態綁定)。

另外註意這裡的幾個階段是按順序開始,而不是按順序進行或完成,因為這些階段通常都是互相交叉地混合進行的,通常在一個階段執行的過程中調用或激活另一個階段。

1.載入

  載入過程完成一下3件事:

  • 獲取一個類全限定名的二進位位元組流。
  • 將靜態存儲結構轉換為方法區的運行時數據結構
  • 記憶體中生產class對象,作為方法區中該類的數據訪問入口

  載入與連接階段交叉進行(但是開始時間順序固定)。

2.驗證

  四個階段:文件格式驗證(驗證規範),元數據驗證(語義校驗),位元組碼驗證(數據流與控制流分析),符號引用認證(符號引用的匹配校驗)。

3.準備:正式分配記憶體並設置變數初始值,記憶體在方法區內分配。

4.解析:將常量池內的符號引用替換為直接引用

  符號引用:一組可以無歧義定位到目標的符號

  直接引用:直接指向目標的指針,相對偏移量或者能間接定位到目標的句柄

5.初始化:根據程式制定的主管計划去初始化變數與資源。

三.類載入器

1.類與類載入器。每一個類載入器都有其獨立的類名稱空間,兩個類由同一個類載入器載入才可能相同,否則必然不同(equals,isAssignableFrom,isInstance)

2.雙親委派機制。

類載入器負責載入所有的類,其為所有被載入記憶體中的類生成一個java.lang.Class實例對象。一旦一個類被載入如JVM中,同一個類就不會被再次載入了。正如一個對象有一個唯一的標識一樣,一個載入JVM的類也有一個唯一的標識。在Java中,一個類用其全限定類名(包括包名和類名)作為標識;但在JVM中,一個類用其全限定類名和其類載入器作為其唯一標識。例如,如果在pg的包中有一個名為Person的類,被類載入器ClassLoader的實例kl負責載入,則該Person類對應的Class對象在JVM中表示為(Person.pg.kl)。這意味著兩個類載入器載入的同名類:(Person.pg.kl)和(Person.pg.kl2)是不同的、它們所載入的類也是完全不同、互不相容的。

JVM預定義有三種類載入器,當一個 JVM啟動的時候,Java開始使用如下三種類載入器:

            

1)根類載入器(bootstrap class loader):它用來載入 Java 的核心類,是用原生代碼來實現的,並不繼承自 java.lang.ClassLoader(負責載入$JAVA_HOME中jre/lib/rt.jar里所有的class,由C++實現,不是ClassLoader子類)。由於引導類載入器涉及到虛擬機本地實現細節,開發者無法直接獲取到啟動類載入器的引用,所以不允許直接通過引用進行操作。

2)擴展類載入器(extensions class loader):它負責載入JRE的擴展目錄,lib/ext或者由java.ext.dirs系統屬性指定的目錄中的JAR包的類。由Java語言實現,父類載入器為null。

3)系統類載入器(system class loader):被稱為系統(也稱為應用)類載入器,它負責在JVM啟動時載入來自Java命令的-classpath選項、java.class.path系統屬性,或者CLASSPATH換將變數所指定的JAR包和類路徑。程式可以通過ClassLoader的靜態方法getSystemClassLoader()來獲取系統類載入器。如果沒有特別指定,則用戶自定義的類載入器都以此類載入器作為父載入器。由Java語言實現,父類載入器為ExtClassLoader。

類載入器載入Class大致要經過如下8個步驟:

  1. 檢測此Class是否載入過,即在緩衝區中是否有此Class,如果有直接進入第8步,否則進入第2步。
  2. 如果沒有父類載入器,則要麼Parent是根類載入器,要麼本身就是根類載入器,則跳到第4步,如果父類載入器存在,則進入第3步。
  3. 請求使用父類載入器去載入目標類,如果載入成功則跳至第8步,否則接著執行第5步。
  4. 請求使用根類載入器去載入目標類,如果載入成功則跳至第8步,否則跳至第7步。
  5. 當前類載入器嘗試尋找Class文件,如果找到則執行第6步,如果找不到則執行第7步。
  6. 從文件中載入Class,成功後跳至第8步。
  7. 拋出ClassNotFountException異常。
  8. 返回對應的java.lang.Class對象。

四、類載入機制:

1.JVM的類載入機制主要有如下3種。

  • 全盤負責:所謂全盤負責,就是當一個類載入器負責載入某個Class時,該Class所依賴和引用其他Class也將由該類載入器負責載入,除非顯示使用另外一個類載入器來載入。
  • 雙親委派:所謂的雙親委派,則是先讓父類載入器試圖載入該Class,只有在父類載入器無法載入該類時才嘗試從自己的類路徑中載入該類。通俗的講,就是某個特定的類載入器在接到載入類的請求時,首先將載入任務委托給父載入器,依次遞歸,如果父載入器可以完成類載入任務,就成功返回;只有父載入器無法完成此載入任務時,才自己去載入。
  • 緩存機制。緩存機制將會保證所有載入過的Class都會被緩存,當程式中需要使用某個Class時,類載入器先從緩存區中搜尋該Class,只有當緩存區中不存在該Class對象時,系統才會讀取該類對應的二進位數據,並將其轉換成Class對象,存入緩衝區中。這就是為很麽修改了Class後,必須重新啟動JVM,程式所做的修改才會生效的原因。

2雙親委派機制:

雙親委派機制,其工作原理的是,如果一個類載入器收到了類載入請求,它並不會自己先去載入,而是把這個請求委托給父類的載入器去執行,如果父類載入器還存在其父類載入器,則進一步向上委托,依次遞歸,請求最終將到達頂層的啟動類載入器,如果父類載入器可以完成類載入任務,就成功返回,倘若父類載入器無法完成此載入任務,子載入器才會嘗試自己去載入,這就是雙親委派模式,即每個兒子都很懶,每次有活就丟給父親去乾,直到父親說這件事我也幹不了時,兒子自己才想辦法去完成。

雙親委派機制的優勢:採用雙親委派模式的是好處是Java類隨著它的類載入器一起具備了一種帶有優先順序的層次關係,通過這種層級關可以避免類的重覆載入,當父親已經載入了該類時,就沒有必要ClassLoader再載入一次。其次是考慮到安全因素,java核心api中定義類型不會被隨意替換,假設通過網路傳遞一個名為java.lang.Integer的類,通過雙親委托模式傳遞到啟動類載入器,而啟動類載入器在核心Java API發現這個名字的類,發現該類已被載入,並不會重新載入網路傳遞的過來的java.lang.Integer,而直接返回已載入過的Integer.class,這樣便可以防止核心API庫被隨意篡改。

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Nio與IO的區別 原有的 IO 是面向流的、阻塞的,NIO 則是面向塊的、非阻塞的。 1.IO流每次從流中讀一個或多個位元組,直至讀完所有位元組,他們沒有被緩存在其他地方,並且,IO流不能移動流中的數據,如果需要前後移動從流中讀取的教據,需要先將它緩存到一個緩衝區。Java NIO的緩衝導向方法略有不 ...
  • 幾個常用的對象 Workbook:工作簿,一個包含多個Sheet的Excel文件 Worksheet:工作表,一個Workbook有多個Worksheet,如“Sheet1”,“Sheet2”等 Cell:單元格,存儲具體的數據對象 導入包 創建Workbook、Worksheet 寫入數據 保存 ...
  • 上面這種方法“無論如何”都讀不出f的內容,使用readlines和迴圈也不行。 但是,用以下的方法,卻可以“正常讀取”: 這是為什麼呢? PS:遇到問題沒人解答?需要Python學習資料?可以加點擊下方鏈接自行獲取 note.youdao.com/noteshare?id=2dce86d0c2588 ...
  • 使用VSCode + NET Core3.0在ASP.NET Core中使用Web API創建 RESTful 服務,包括創建簡單Rest API、格式化輸出、JSON Patch請求、Open API(Swagger)集成 ...
  • asp.net core 從 3.0 到 3.1 Intro 今天 .net core 3.1 正式發佈了,.net core 3.1 正式版已發佈,3.1 主要是對 3.0 的 bug 修複,以及一些小優化,而且作為 LTS 版本,建議大家升級。值得一提的是.net core 2.2 這個月就要壽 ...
  • 目 錄 1. 概述... 2 2. 演示信息... 2 3. 簡單介紹... 3 4. 產品特點... 4 5. 價值體現... 5 1. 概述 經過一段時間的努力,iNeuDA產品組件已經開發和測試完成,現在正式上線。現在iNeuOS工業互聯網操作系統的技術體系和產品體系更佳完善,為中小企業提供更 ...
  • Net Core 2.x 跟 Net Core3.0 還是有很大的區別的,隨著.NET Core 3.1發佈,也就意味著老版本慢慢的要停止維護。 Net Core 3.0 其實就是過渡版本,用於我們練手。 ASP.NET Core 2.2 遷移到3.0:https://docs.microsoft. ...
  • 參考博客: https://blog.csdn.net/flyer_tang/article/details/80320974 https://blog.csdn.net/weixin_30773135/article/details/97923338 官網下載地址: http://redis.io ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...