面試常備題---JVM加載class文件的原理機制


      在面試java工程師的時候,這道題經常被問到,故需特別注意。

      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()才會成為一般程序的入口方法。類的構造器也會引發該動作。

    

 

    


免責聲明!

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



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