關於 Java ClassLoader 你真的瞭解嗎

背景

類加載機制作為一個高頻的面試題經常會在面試中被問到,前幾天一個電話面試就問到,之前有了解過,但是沒有梳理成自己的體系,所以說的有點凌亂,今天花點時間整理一下,分享給大家同時自己也好好梳理一下,順便幫助一下有需要的人。


什麼是類加載機制

眾所周知我們編寫的 Java 文件都是以.java 為後綴的文件,編譯器會將我們編寫的.java 的文件編譯成.class 文件,簡單來說類加載機制就是從文件系統將一系列的 class 文件讀入 JVM 內存中為後續程序運行提供資源的動作。

類加載的流程

我們先看下類加載的過程中有哪些階段,後面再對其一一解釋做了什麼。


關於 Java ClassLoader 你真的瞭解嗎


簡單畫了一個圖,從上圖我們可以看出,類加載的整個過程有五個階段,下面分別解釋每個過程做了什麼。

加載

通過一個類的完整路徑查找此類字節碼文件(class 文件即二進制文件)。將二進制文件的靜態存儲結構轉化為方法區的運行時數據結構,並利用二進制流文件創建一個Class對象,存儲在 Java 堆中用於對方法區的數據結構引用的入口;

  1. class 文件的來源:有一點需要注意的是類加載機制不僅可以從文件系統讀取 class 文件,也可以通過網絡獲取,其他 jar 包或者其他程序生成,如 JSP 應用。
  2. 類加載器:講到類加載不得不講到類加載的順序和類加載器。Java 中大概有四種類加載器,分別是:啟動類加載器(Bootstrap ClassLoader),擴展類加載器(Extension ClassLoader),系統類加載器(System ClassLoader),自定義類加載器(Custom ClassLoader),依次屬於繼承關係(注意這裡的繼承不是 Java 類裡面的 extends)
  3. 啟動類加載器(Bootstrap ClassLoader):主要負責加載存放在Java_Home/jre/lib下,或被-Xbootclasspath參數指定的路徑下的,並且能被虛擬機識別的類庫(如rt.jar,所有的java.*開頭的類均被Bootstrap ClassLoader加載),啟動類加載器是無法被Java程序直接引用的。
  4. 擴展類加載器(Extension ClassLoader):主要負責加載器由sun.misc.Launcher$ExtClassLoader實現,它負責加載Java_Home/jre/lib/ext目錄中,或者由java.ext.dirs系統變量指定的路徑中的所有類庫(如javax.*開頭的類),開發者可以直接使用擴展類加載器。
  5. 系統類加載器(System ClassLoader):主要負責加載器由sun.misc.Launcher$AppClassLoader來實現,它負責加載用戶類路徑(ClassPath)所指定的類,開發者可以直接使用該類加載器,如果應用程序中沒有自定義過自己的類加載器,一般情況下這個就是程序中默認的類加載器。
  6. 自定義類加載器(Custom ClassLoader:自己開發的類加載器
  7. 雙親委派原則:類加載器在加載 class 文件的時候,遵從雙親委派原則,意思是加載依次由父加載器先執行加載動作,只有當父加載器沒有加載到 class 文件時才由子類加載器進行加載。這種機制很好的保證了 Java API 的安全性,使得 JDK 的代碼不會被篡改。

驗證

驗證的過程只要是保證 class 文件的安全性和正確性,確保加載了該 class 文件不會導致 JVM 出現任何異常,不會危害JVM 的自身安全。驗證包括對文件格式的驗證,元數據和字節碼的驗證。

準備

準備階段是為類變量進行內存分配和初始化零值的過程。注意這時候分配的是類變量的內存,這些內存會在方法區中分配。此時不會分配實例變量的內存,因為實例變量是在實例化對象時一起創建在Java 堆中的。而且此時類變量是賦值為零值,即 int 類型的零值為 0,引用類型零值為 null,而不是代碼中顯示賦值的數值。

解析

解析階段是虛擬機將常量池中的符號引用轉化為直接引用的過程。在 class 文件中常量池裡面存放了字面量和符號引用,符號引用包括類和接口的全限定名以及字段和方法的名稱與描述符。在 JVM 動態鏈接的時候需要根據這些符號引用來轉換為直接引用存放內存使用。

初始化

初始化的階段是類加載的最後一步,這個階段主要是執行 java 代碼,進行相關初始化的動作。

總結

整個類加載機制是我們程序運行的開始,雖然這些動作都是 JVM 幫我們自動完成,開發人員在不需要定製類加載器的時候是不會涉及到底層細節的,但是作為一個有追求的程序員,我們還是要知道一些原理,這樣不管是在面試的時候還是對自己的提升都有很大的幫助。


分享到:


相關文章: