Java虛擬機器類裝載:原理、實現與應用
Java虛擬機器類裝載:原理、實現與應用[@more@] 一、引言
Java虛擬機器(JVM)的類裝載就是指將包含在類檔案中的位元組碼裝載到JVM中, 並使其成為JVM一部分的過程。JVM的類動態裝載技術能夠在執行時刻動態地載入或者替換系統的某些功能模組, 而不影響系統其他功能模組的正常執行。本文將分析JVM中的類裝載系統,探討JVM中類裝載的原理、實現以及應用。
二、Java虛擬機器的類裝載實現與應用
2.1 裝載過程簡介
所謂裝載就是尋找一個類或是一個介面的二進位制形式並用該二進位制形式來構造代表這個類或是這個介面的class物件的過程,其中類或介面的名稱是給定了的。當然名稱也可以透過計算得到,但是更常見的是透過搜尋原始碼經過編譯器編譯後所得到的二進位制形式來構造。
在Java中,類裝載器把一個類裝入Java虛擬機器中,要經過三個步驟來完成:裝載、連結和初始化,其中連結又可以分成校驗、準備和解析三步,除了解析外,其它步驟是嚴格按照順序完成的,各個步驟的主要工作如下:
裝載:查詢和匯入類或介面的二進位制資料;
連結:執行下面的校驗、準備和解析步驟,其中解析步驟是可以選擇的;
校驗:檢查匯入類或介面的二進位制資料的正確性;
準備:給類的靜態變數分配並初始化儲存空間;
解析:將符號引用轉成直接引用;
初始化:啟用類的靜態變數的初始化Java程式碼和靜態Java程式碼塊。
至於在類裝載和虛擬機器啟動的過程中的具體細節和可能會丟擲的錯誤,請參看《Java虛擬機器規範》以及《深入Java虛擬機器》,它們在網路上面的資源地址是:
由於本文的討論重點不在此就不再多敘述。
2.2 裝載的實現
JVM中類的裝載是由ClassLoader和它的子類來實現的,Java ClassLoader 是一個重要的Java執行時系統元件。它負責在執行時查詢和裝入類檔案的類。
在Java中,ClassLoader是一個抽象類,它在包java.lang中,可以這樣說,只要瞭解了在ClassLoader中的一些重要的方法,再結合上面所介紹的JVM中類裝載的具體的過程,對動態裝載類這項技術就有了一個比較大概的掌握,這些重要的方法包括以下幾個:
①loadCass方法 loadClass(String name ,boolean resolve)其中name引數指定了JVM需要的類的名稱,該名稱以包表示法表示,如Java.lang.Object;resolve引數告訴方法是否需要解析類,在初始化類之前,應考慮類解析,並不是所有的類都需要解析,如果JVM只需要知道該類是否存在或找出該類的超類,那麼就不需要解析。這個方法是ClassLoader 的入口點。
②defineClass方法 這個方法接受類檔案的位元組陣列並把它轉換成Class物件。位元組陣列可以是從本地檔案系統或網路裝入的資料。它把位元組碼分析成執行時資料結構、校驗有效性等等。
③findSystemClass方法 findSystemClass方法從本地檔案系統裝入檔案。它在本地檔案系統中尋找類檔案,如果存在,就使用defineClass將位元組陣列轉換成Class物件,以將該檔案轉換成類。當執行Java應用程式時,這是JVM 正常裝入類的預設機制。
④resolveClass方法 resolveClass(Class c)方法解析裝入的類,如果該類已經被解析過那麼將不做處理。當呼叫loadClass方法時,透過它的resolve 引數決定是否要進行解析。
⑤findLoadedClass方法 當呼叫loadClass方法裝入類時,呼叫findLoadedClass 方法來檢視ClassLoader是否已裝入這個類,如果已裝入,那麼返回Class物件,否則返回NULL。如果強行裝載已存在的類,將會丟擲連結錯誤。
2.3 裝載的應用
一般來說,我們使用虛擬機器的類裝載時需要繼承抽象類java.lang.ClassLoader,其中必須實現的方法是loadClass(),對於這個方法需要實現如下操作:(1) 確認類的名稱;(2) 檢查請求要裝載的類是否已經被裝載;(3) 檢查請求載入的類是否是系統類;(4) 嘗試從類裝載器的儲存區獲取所請求的類;(5) 在虛擬機器中定義所請求的類;(6) 解析所請求的類;(7) 返回所請求的類。
所有的Java 虛擬機器都包括一個內建的類裝載器,這個內建的類庫裝載器被稱為根裝載器(bootstrap ClassLoader)。根裝載器的特殊之處是它只能夠裝載在設計時刻已知的類,因此虛擬機器假定由根裝載器所裝載的類都是安全的、可信任的,可以不經過安全認證而直接執行。當應用程式需要載入並不是設計時就知道的類時,必須使用使用者自定義的裝載器(user-defined ClassLoader)。下面我們舉例說明它的應用。
public abstract class MultiClassLoader extends ClassLoader{
...
public synchronized Class loadClass(String s, boolean flag)
throws ClassNotFoundException
{
/* 檢查類s是否已經在本地記憶體*/
Class class1 = (Class)classes.get(s);
/* 類s已經在本地記憶體*/
if(class1 != null) return class1;
try/*用預設的ClassLoader 裝入類*/ {
class1 = super.findSystemClass(s);
return class1;
}
catch(ClassNotFoundException _ex) {
System.out.println(">> Not a system class.");
}
/* 取得類s的位元組陣列*/
byte abyte0[] = loadClassBytes(s);
if(abyte0 == null) throw new ClassNotFoundException();
/* 將類位元組陣列轉換為類*/
class1 = defineClass(null, abyte0, 0, abyte0.length);
if(class1 == null) throw new ClassFormatError();
if(flag) resolveClass(class1); /*解析類*/
/* 將新載入的類放入本地記憶體*/
classes.put(s, class1);
System.out.println(">> Returning newly loaded class.");
/* 返回已裝載、解析的類*/
return class1;
}
...
}
Java虛擬機器(JVM)的類裝載就是指將包含在類檔案中的位元組碼裝載到JVM中, 並使其成為JVM一部分的過程。JVM的類動態裝載技術能夠在執行時刻動態地載入或者替換系統的某些功能模組, 而不影響系統其他功能模組的正常執行。本文將分析JVM中的類裝載系統,探討JVM中類裝載的原理、實現以及應用。
二、Java虛擬機器的類裝載實現與應用
2.1 裝載過程簡介
所謂裝載就是尋找一個類或是一個介面的二進位制形式並用該二進位制形式來構造代表這個類或是這個介面的class物件的過程,其中類或介面的名稱是給定了的。當然名稱也可以透過計算得到,但是更常見的是透過搜尋原始碼經過編譯器編譯後所得到的二進位制形式來構造。
在Java中,類裝載器把一個類裝入Java虛擬機器中,要經過三個步驟來完成:裝載、連結和初始化,其中連結又可以分成校驗、準備和解析三步,除了解析外,其它步驟是嚴格按照順序完成的,各個步驟的主要工作如下:
裝載:查詢和匯入類或介面的二進位制資料;
連結:執行下面的校驗、準備和解析步驟,其中解析步驟是可以選擇的;
校驗:檢查匯入類或介面的二進位制資料的正確性;
準備:給類的靜態變數分配並初始化儲存空間;
解析:將符號引用轉成直接引用;
初始化:啟用類的靜態變數的初始化Java程式碼和靜態Java程式碼塊。
至於在類裝載和虛擬機器啟動的過程中的具體細節和可能會丟擲的錯誤,請參看《Java虛擬機器規範》以及《深入Java虛擬機器》,它們在網路上面的資源地址是:
由於本文的討論重點不在此就不再多敘述。
2.2 裝載的實現
JVM中類的裝載是由ClassLoader和它的子類來實現的,Java ClassLoader 是一個重要的Java執行時系統元件。它負責在執行時查詢和裝入類檔案的類。
在Java中,ClassLoader是一個抽象類,它在包java.lang中,可以這樣說,只要瞭解了在ClassLoader中的一些重要的方法,再結合上面所介紹的JVM中類裝載的具體的過程,對動態裝載類這項技術就有了一個比較大概的掌握,這些重要的方法包括以下幾個:
①loadCass方法 loadClass(String name ,boolean resolve)其中name引數指定了JVM需要的類的名稱,該名稱以包表示法表示,如Java.lang.Object;resolve引數告訴方法是否需要解析類,在初始化類之前,應考慮類解析,並不是所有的類都需要解析,如果JVM只需要知道該類是否存在或找出該類的超類,那麼就不需要解析。這個方法是ClassLoader 的入口點。
②defineClass方法 這個方法接受類檔案的位元組陣列並把它轉換成Class物件。位元組陣列可以是從本地檔案系統或網路裝入的資料。它把位元組碼分析成執行時資料結構、校驗有效性等等。
③findSystemClass方法 findSystemClass方法從本地檔案系統裝入檔案。它在本地檔案系統中尋找類檔案,如果存在,就使用defineClass將位元組陣列轉換成Class物件,以將該檔案轉換成類。當執行Java應用程式時,這是JVM 正常裝入類的預設機制。
④resolveClass方法 resolveClass(Class c)方法解析裝入的類,如果該類已經被解析過那麼將不做處理。當呼叫loadClass方法時,透過它的resolve 引數決定是否要進行解析。
⑤findLoadedClass方法 當呼叫loadClass方法裝入類時,呼叫findLoadedClass 方法來檢視ClassLoader是否已裝入這個類,如果已裝入,那麼返回Class物件,否則返回NULL。如果強行裝載已存在的類,將會丟擲連結錯誤。
2.3 裝載的應用
一般來說,我們使用虛擬機器的類裝載時需要繼承抽象類java.lang.ClassLoader,其中必須實現的方法是loadClass(),對於這個方法需要實現如下操作:(1) 確認類的名稱;(2) 檢查請求要裝載的類是否已經被裝載;(3) 檢查請求載入的類是否是系統類;(4) 嘗試從類裝載器的儲存區獲取所請求的類;(5) 在虛擬機器中定義所請求的類;(6) 解析所請求的類;(7) 返回所請求的類。
所有的Java 虛擬機器都包括一個內建的類裝載器,這個內建的類庫裝載器被稱為根裝載器(bootstrap ClassLoader)。根裝載器的特殊之處是它只能夠裝載在設計時刻已知的類,因此虛擬機器假定由根裝載器所裝載的類都是安全的、可信任的,可以不經過安全認證而直接執行。當應用程式需要載入並不是設計時就知道的類時,必須使用使用者自定義的裝載器(user-defined ClassLoader)。下面我們舉例說明它的應用。
public abstract class MultiClassLoader extends ClassLoader{
...
public synchronized Class loadClass(String s, boolean flag)
throws ClassNotFoundException
{
/* 檢查類s是否已經在本地記憶體*/
Class class1 = (Class)classes.get(s);
/* 類s已經在本地記憶體*/
if(class1 != null) return class1;
try/*用預設的ClassLoader 裝入類*/ {
class1 = super.findSystemClass(s);
return class1;
}
catch(ClassNotFoundException _ex) {
System.out.println(">> Not a system class.");
}
/* 取得類s的位元組陣列*/
byte abyte0[] = loadClassBytes(s);
if(abyte0 == null) throw new ClassNotFoundException();
/* 將類位元組陣列轉換為類*/
class1 = defineClass(null, abyte0, 0, abyte0.length);
if(class1 == null) throw new ClassFormatError();
if(flag) resolveClass(class1); /*解析類*/
/* 將新載入的類放入本地記憶體*/
classes.put(s, class1);
System.out.println(">> Returning newly loaded class.");
/* 返回已裝載、解析的類*/
return class1;
}
...
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10901326/viewspace-965621/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java虛擬機器類裝載的原理及實現Java虛擬機
- java虛擬機器類載入機制Java虛擬機
- Java 虛擬機器類載入機制Java虛擬機
- Java虛擬機器10:類載入器Java虛擬機
- 虛擬機器遷移技術原理與應用虛擬機
- Java虛擬機器9:Java類載入機制Java虛擬機
- Java虛擬機器(六):類載入機制Java虛擬機
- Java虛擬機器 —— 類的載入機制Java虛擬機
- Java 虛擬機器之四:Java類載入機制Java虛擬機
- JVM(三)-java虛擬機器類載入機制JVMJava虛擬機
- Dalvik虛擬機器、Java虛擬機器與ART虛擬機器虛擬機Java
- Java虛擬機器類載入的過程Java虛擬機
- Java跨平臺原理與Java虛擬機器(JVM)Java虛擬機JVM
- 虛擬機器類載入機制虛擬機
- 深入理解Java虛擬機器(類載入機制)Java虛擬機
- 【Java虛擬機器規範】JVM類載入機制Java虛擬機JVM
- 深入理解Java虛擬機器 - 類載入機制Java虛擬機
- 深入理解Java虛擬機器 --- 類載入機制Java虛擬機
- 虛擬機器類載入機制:類載入時機虛擬機
- 深入理解虛擬機器之虛擬機器類載入機制虛擬機
- JVM虛擬機器和類載入器JVM虛擬機
- java虛擬機器的執行原理Java虛擬機
- 虛擬機器類載入機制_類載入的過程虛擬機
- JVM(7)-虛擬機器類載入機制JVM虛擬機
- JVM(五)----虛擬機器類載入機制JVM虛擬機
- 虛擬機器系列 | JVM類載入機制虛擬機JVM
- (深入理解 Java虛擬機器)一篇文章帶你深入瞭解Java 虛擬機器類載入器Java虛擬機
- 《深入理解java虛擬機器》第七章讀書筆記——虛擬機器類載入機制Java虛擬機筆記
- [深入理解Java虛擬機器]第七章 類載入器Java虛擬機
- Java虛擬機器——類檔案結構Java虛擬機
- JVM學習-虛擬機器類載入機制JVM虛擬機
- Android虛擬機器框架:類載入機制Android虛擬機框架
- java虛擬機器和Dalvik虛擬機器Java虛擬機
- Android 虛擬機器 Vs Java 虛擬機器Android虛擬機Java
- Java虛擬機器是怎麼實現synchronized的Java虛擬機synchronized
- 《深入理解java虛擬機器》學習筆記7——Java虛擬機器類生命週期Java虛擬機筆記
- 應用虛擬機器VMware安裝archlabs系統虛擬機
- 面試官,不要再問我“Java虛擬機器類載入機制”了面試Java虛擬機