JVM載入Class檔案的原理機制

廣大青年發表於2020-09-21

前言

瞭解底層有利於我們去開發專案,廢話少說,我們開始吧

目錄

1.原理機制

2.類載入器

3.類載入器的執行過程

4.雙親委派模型

 

一、原理機制

1.1簡述java類載入機制:

虛擬機器(jvm)把描述類的資料從Class檔案載入到記憶體,並對資料進行校驗,解析和初始化,最終形成可以被虛擬機器直接使用的java型別。

1.2描述一下JVM載入Class檔案的原理機制

java中的所有類,都需要有由類載入器裝載到JVM中才能執行。類載入器本身也是一個類,而它的工作就是把Class檔案從硬碟讀取到記憶體中。在寫程式的時候,我們幾乎不需要關心類的載入,因為這些都是隱式裝載的,除非我們有特殊的用法,像是反射,就需要顯示的載入所需要的類。

類裝載的方式,有兩種:

1、隱式裝載,程式在執行過程中當碰到通過new等方式生成物件時,隱式呼叫類裝載器對應的類到jvm中

2、顯示裝載,通過class.forname()等方式,顯示載入需要的類

java類的載入是動態的,它並不會一次性將所有類全部載入後再執行,而是儲存程式執行的基礎類(像是基類)完全載入到JVM中,至於其他類,則在需要的時候才才載入。這當然就是為了節省記憶體開銷

二、類載入器

隱式裝載和顯示裝載都是由類載入器來進行

2.1、什麼是類載入器,類載入器有哪些

實現通過類的全限定名獲取該類的二進位制位元組流的程式碼塊叫做類載入器。

主要有以下四種類載入器:

1、啟動類載入器(Bootstrap ClassLoader)用來載入java核心類庫,無法被java程式直接引用。

2、擴充套件類載入器(Extensions ClassLoader)用來載入java的擴充套件庫。java虛擬機器的實現會提供一個擴充套件庫目錄。該類載入器在此目錄裡面查詢並載入java類。

3、系統類載入器(System ClassLoader)根據java應用的類路徑(CLASSPATH)來載入java類。一般來說,java應用的類都是由它來完成載入的。可以通過ClassLoader.getSystemLoader()來獲取它。

4、使用者自定義類載入器,通過繼承java.lang.ClassLoader類的方式實現。

2.2類裝載的執行過程

類裝載分為以下5個步驟:

  • 載入:根據查詢路徑找到相應的class問價然後匯入;
  • 驗證:檢查載入的class檔案的正確性;
  • 準備:給類中的靜態標量分配記憶體空間;
  • 解析:虛擬機器將常量池中的符號引用替換成直接引用的過程。符號引用就理解為一個標示,而在直接引用直接指向記憶體中的地址;
  • 初始化:對靜態變數和靜態程式碼塊進行初始化工作;

三、雙親委派模型

在介紹雙親委派模型之前回顧一下類載入器。對於任意一個類,都需要由載入它的類載入器和這個類本身一同確立在JVM中的唯一性,每個類載入器,都有一個獨立的類名稱空間。類載入器就是根據全限定名將class檔案載入到JVM中,然後再轉化為class物件。

 

 類載入器分類:

  • 啟動類載入器(Bootstrap ClassLoader),是虛擬機器自身的一部分,用來載入Java_HOME/lib目錄中的,或者被-Xbootclasspath引數所指定的路徑中並且被虛擬機器識別的類庫;
  • 擴充套件類載入器(Extension ClassLoader),負責載入\lib\ext目錄或Java.ext.dirs系統變數所指定的路徑中的所有類庫;
  • 應用程式類載入器(Application ClassLoader),負責載入使用者類路徑(classpath)上的指定類庫,我們可以直接使用這個類載入器。一般情況下,我們沒有自定義類載入器,預設就是用這個載入器。

雙親委派模型:如果一個類載入器收到了類載入的請求,他首先不會自己去載入這個類,而是把這個請求委派給父類載入器去完成,每一層的類載入器都是如此,這樣所有的載入請求都會被傳送到頂層的啟動類載入器中,只有當父類載入器無法完成載入請求(它的搜素範圍中沒找到所需的類)時,子載入器才會嘗試去載入類。

當一個類收到了類載入請求時,不會自己先去載入這個類,而是將其委派給父類,如果此時父類不能載入,反饋給子類,由子類去完成類的載入。

  每日一囧,微笑面對生活,我是懂先森,你們的廣大青年。

 

相關文章