1. 程式人生 > >JVM執行和類載入過程

JVM執行和類載入過程

JVM執行和類載入過程

類載入機制:
JVM把 class 檔案載入到記憶體,並對資料進行校驗、解析和初始化,最終形成JVM可以直接使用的 Java 型別的過程
類載入過程

  1. 載入
    將 class 檔案位元組碼內容載入到記憶體隨,並將這些靜態資料轉換成方法區中的執行時資料結構,在堆中生產一個代表這個類的java.lang.Class物件,作為方法區類資料的訪問入口
  2. 連結
    • 驗證:確保載入的類資訊符合JVM規範,沒有安全方面的問題
    • 準備:正式為類變數(static)分配記憶體並設定類變數初始值的階段,並在方法區中分配
    • 解析:虛擬機器常量池內的符合引用替換直接直接應用的過程
  3. 初始化
    初始化階段時執行類構造器()方法的過程。類構造器()方法是由編譯器自動收集類中的所有類變數的賦值動作和靜態語句塊(static塊)中的語句合併產生的
    當初始化一個類時,如果發現其父類還沒有初始化過,則需要先觸發其父類的初始化
    虛擬機器會保證一個類的()方法在多執行緒環境中被正確加鎖和同步

類的引用:

  • 主動:
    • new一個類物件
    • 呼叫類的靜態成員(final 常量除外)和靜態方法
    • 使用java.lang.reflect包的方法對類進行反射呼叫
    • 當虛擬機器啟動,則一定會初始化類
    • 初始化時,若父類沒有被初始化,則先初始化其父類
  • 被動:
    • 當訪問一個靜態域時,只有真正宣告這個域的類才會被初始化,通過子類引用父類的靜態變數,不會導致子類初始化
    • 通過陣列定義類引用,不會觸發類的初始化
    • 引用常量不會觸發類初始化

類載入器

類載入器原理

將class檔案位元組碼內容載入到記憶體中,並將這些靜態資料轉換成方法區中的執行時資料結構,在堆中生產一個代表這個類的 java.lang.Class 物件,作為方法區類資料的訪問入口

類快取:

標準的 Java SE類載入器可以按要求查詢類,若某個類載入到類載入器中,將維持載入一定時間(快取),後期被 JVM 垃圾回收器回收

ClassLoader類:

根據指定的類名稱,找到或生成對應的位元組程式碼,然後從這些位元組程式碼中定義出一個 Java 類,即 java.lang.Class 類的一個例項
ClassLoader 還負責載入 Java 應用所需的資源,如影象檔案和配置檔案等。


類載入器樹狀結構、雙親委託代理機制

類載入結構
啟動類載入器:

載入 Java 的核心庫(JAVA_HOME/jre/lib/rt.jar)
載入擴充套件類和應用程式類載入器,並指定他們的父類載入器

擴充套件類載入器:

載入 Java 擴充套件庫(jre/ext/*.jar),Java 虛擬機器的實現會提供一個擴充套件庫目錄,該類載入器在此目錄中查詢並載入 Java 類

應用程式類載入器:

根據 Java 應用的類路徑classpath來載入類,一般使用的類都是其載入的

自定義類載入器:

通過繼承ClassLoader類實現自定義類載入器

雙親委託機制:

當類載入器在接收到載入類請求時,先將載入任務委託給父類載入器,依次追溯,直到最高的類載入器,如果父類完成載入任務,則返回成功,否則子類去完成載入任務
雙親委託機制時為了保證 Java 核心庫的型別安全,杜絕了使用者自定義Object類的情況
類載入器除了用於載入類,也是安全的最基本屏障

  • 雙親委託機制是代理模式的一種,並不是所有的類載入器都採用此模式,Tomcat伺服器使用的代理模式則不同,其先載入某個類,若不成功再委託給父類載入器

半臉懵逼