深入研究Java類裝載機制


目錄

1.為什么要研究java類裝在機制?

2.了解類裝載機制,對於我們在項目開發中有什么作用?

3.裝載實現細節。

4.總結

 

一、為什么葯研究Java類裝載機制

  java類加載機制,便於我們使用自定義類加載器;深入理解,對於理解編譯原理也有很大幫助。

二、了解類裝載機制,在我們項目開始中的應用

  在項目中,我們可以使用自定義類加載器,可以幫助我們做如下操作:

  (1)加密。java代碼很容易被反編譯,如果你需要把自己的代碼進行加密,可以先將編譯后的代碼用某種加密算法加密,然后實現自己的類加載器,負責將這段加密后的代碼還原,以被操作系統所識別。這樣,別人看到的是加密后的.class文件,無法進行反編譯。

  (2)從指定來源加載。如果字節碼文件不是采用標准的方式來加載代碼,可能從數據庫或者網絡上加載,就需要自定義類加載器,從指定路徑加載類文件。

  (3)性能。基於實際情況,動態創建代碼並執行。

三、java類裝載機制原理

  Java程序被執行的流程圖如下:Java源文件(*.java)==》java編譯器==》字節碼文件(*.class)==》類裝載器==》字節碼校驗器==》解釋器==》操作系統,整個文件被load到內存區,一系列動作之后,最終形成了操作系統可以識別的代碼,操作系統找到main方法開始執行。其中,heap(new出來的東西放在里面)、stack(局部變量)、data segment(靜態變量或字符串常量)、code segment(存放代碼)。


如上圖所示,public static void main(String args[])被編譯到操作系統中后,作為程序的入口,開始執行。接下來分析一下這個過程

   

如左圖所示,JRE提供的jar包,正如名字一樣,它提供了java運行時環境。右圖是Hello World被編譯為.class文件后的效果。一個java類被加載的過程如下:

1、使用命令執行javac Main.java,生成Main.class文件;執行java Main命令,JVM會將Main.class加載到內存中,並形成一個class的對象Main.class。關於Class對象和Object對象的區別,參考附錄一。

2、JVM將Main.class加載到內存如下:首先,尋找JRE目錄,找到jvm.dll,並初始化JVM;然后產生一個Bootstrap Loader(啟動類加載器),Bootstrap Loader自動加載Extended Loader(標准擴展類加載器),並將其父loader設置為Bootstrap loader;Bootstrap Loader自動加載Appclass loader(系統類加載器),並將其父loader設為Extended Loader。最后由Appclass loader加載Main類。

即:Bootstrap loader==》Extended Loader==》Appclass loader(*.class文件說明見附錄二)

3、接着第二部,在裝載過程中,如編譯原理中所描述,要依次進行如下步驟。類加載器appclass loader尋找類的字節碼文件Main.class,並且構造出類的JVM內部表示的對象組件。

  (1)裝載,查找和導入class文件。

  (2)鏈接,把二進制數據合並到JRE中。

    (a)校驗:檢查載入class文件數據的正確性

    (b)准備:給類的靜態變量分配存儲空間

    (c)解析:將符號引用轉成直接引用

  (3)初始化,對類的靜態變量,靜態代碼塊進行初始化操作。

4、常用方法:

 

ClassLoader loader = Main.class.getClassLoader(); 
loader.loadClass("Main"); 

類加載有三種方式:
1、命令行啟動應用時候由JVM初始化加載
2、通過Class.forName()方法動態加載
3、通過ClassLoader.loadClass()方法動態加載

 

四、總結

  類的加載,最終從硬盤加載到內存當中,變成基於操作系統可以識別的二進制文件流來執行,因此,優化代碼,需要掌握JVM在內存當中的布局。

附錄一:Object和Class兩個類之間的區別

  Object是所有類的父類,所有類當然也包括Class類。所以,Object類是Class類的父類。

 

private Class(ClassLoader loader) {
    // Initialize final field for classLoader.  The initialization value of non-null
    // prevents future JIT optimizations from assuming this final field is null.
    classLoader = loader;
}

 

  Class這個類,構造方法是私有的。所以不能顯示的new 一個class對象。它是用來描述一個對象的元信息的。

附錄二:*.class文件說明

  Java的Class文件是有8個字節為基礎的字節流構成的,這些字節流之間都嚴格按照規定的順序排列,並且字節之間不存在任何空隙,對於超過8個字節的數據,將按照Big-Endian的順序存儲的,也就是說高位字節存儲在低的地址上面,而低位字節存儲到高地址上面,其實這也是class文件要跨平台的關鍵。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM