1. 程式人生 > >JAVA面試常備題、JVM載入class檔案的原理機制

JAVA面試常備題、JVM載入class檔案的原理機制

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

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

Java的類載入器有三個,對應Java的三種類:

Bootstrap Loader // 負責載入系統類 (指的是內建類,像是String,對應於C#中的System類和C/C++標準庫中的類)
|
- - ExtClassLoader //負責載入擴充套件類(就是繼承類和實現類)
|
- - AppClassLoader //負責載入應用類(程式設計師自定義的類)

三個載入器各自完成自己的工作,但它們是如何協調工作呢?哪一個類該由哪個類載入器完成呢?為了解決這個問題,Java採用了委託模型機制。

委託模型機制的工作原理很簡單:當類載入器需要載入類的時候,先請示其Parent(即上一層載入器)在其搜尋路徑載入,如果找不到,才在自己的搜尋路徑搜尋該類。這樣的順序其實就是載入器層次上自頂而下的搜尋,因為載入器必須保證基礎類的載入。之所以是這種機制,還有一個安全上的考慮:如果某人將一個惡意的基礎類載入到jvm,委託模型機制會搜尋其父類載入器,顯然是不可能找到的,自然就不會將該類載入進來。

我們可以通過這樣的程式碼來獲取類載入器:

ClassLoader loader = ClassName.class.getClassLoader();
ClassLoader ParentLoader = loader.getParent();

注意一個很重要的問題,就是Java在邏輯上並不存在BootstrapKLoader的實體!因為它是用C++編寫的,所以列印其內容將會得到null。
前面是對類載入器的簡單介紹,它的原理機制非常簡單,就是下面幾個步驟:

1.裝載:查詢和匯入class檔案;

2.連線:

(1)檢查:檢查載入的class檔案資料的正確性;

(2)準備:為類的靜態變數分配儲存空間;

(3)解析:將符號引用轉換成直接引用(這一步是可選的)

3.初始化:初始化靜態變數,靜態程式碼塊。

這樣的過程在程式呼叫類的靜態成員的時候開始執行,所以靜態方法main()才會成為一般程式的入口方法。類的構造器也會引發該動作。