JAVA虛擬機之類加載器

轉載請聲明:原文轉自http://www.cnblogs.com/xiezie/p/5909570.html html

1.JVM的生命週期

1.1 JVM的生命週期和程序的生命週期一致

1.2 JVM結束生命週期的狀況

1.執行System.exit(int n);//0爲正常關閉,!0爲異常關閉
2.系統拋出未捕獲的異常,或者拋出錯誤
3.操做系統錯誤,致使JAVA進程關閉
4.正常執行結束java

 

2. JAVA程序對類的使用方式

1.主動使用:

  • -建立類的實例對象
  • -類被靜態調用
    1. -類的靜態成員變量被調用或者賦值
    2. -類的靜態方法被調用
  • -其子類被主動使用
  • -經過反射調用
  • -Java虛擬機啓動時被標明爲啓動類的類(包含main方法)

2.被動使用:

除了被主動使用以外的方式都屬於被動使用(經過classloader.loadclass也算被動使用)數據庫


3.類加載器的加載、鏈接及初始化

3.1 加載:查找並加載類的二進制文件

1.類加載器的共性

  • 除了根加載器,每一個類加載器都有一個父類加載器(可是父子間並不是必定是繼承關係,實現方式是包裝、修飾方式)
ClassLoader parent;
protected ClassLoader() {
    this(checkCreateClassLoader()//安全監測
        , getSystemClassLoader());//默認設置父類加載器是系統加載器
}
protected ClassLoader(ClassLoader parent) {
    this(checkCreateClassLoader(), parent);
}
  • 每一個加載器都有命名空間(命名空間由該加載器和其父類加載器加載的類構成)
  • 類的加載機制是父親委託機制(基於安全性的考慮),即加載類的時候先找父類加載器,沒有的時候再找子類加載

   實際加載類的類加載器爲定義類加載器,其包括其一下的類加載器爲初始類加載器安全

  • .class的獲取:
    • 經過直接加載.class文件(如Elipse編譯生成的class文件)
    • 從網絡獲取.class文件————(如URLClassLoader)
    • 從ZIP、jar文件中加載.class文件
    • 動態編譯生成
    • 從專用數據庫中獲取
  • 類加載的時機:
    • JVM規範容許類加載器在預料某個類將要被使用時就預先加載它
    • 類加載器並不須要等到某個類被「首次主動使用」時再加載它
  • 類加載的最終產品是位於堆中的class對象(封裝類的方法區內的數據結構)、並且在方法區中放入類的數據結構的接口

2.分類:

  1. 根加載器(Bootstrap):
    • 若是從JAVA代碼中獲取JAVA核心類庫的加載器會返回null——這個加載器沒法從java層獲取
    • 由JAVA底層的C++實現、執行調用,主要負責加載JVM的核心類庫,如執行Java.lang.*包下的一些類
    • 沒有父類加載器,也不繼承ClassLoader
  2. 擴展加載器(Extension):ExtClassLoader  
    • 主要負責加載java.ext.dirs目錄下的類庫,或者是JRE目錄下的lib\ext目錄下的類庫,放在這個目錄下的jar文件也由擴展加載器自動加載
    • ClassLoader的子類
  3. 系統加載器(System):也稱爲應用加載器,AppClassLoader
    • 主要負責環境變量中的ClassPath目錄下的類加載

3.類加載錯誤

  • 若是在預先加載的過程當中遇到了.class文件缺失或存在錯誤,類加載器必須在程序首次主動使用該類時才報告錯誤(LinkageError錯誤)
  • 若是這個類一直沒有被程序主動使用,那麼類加載器就不會報告錯誤


3.2 鏈接:將加載到內存的二進制數據合併到JAVA運行時環境

1.驗證:確保被加載類的正確性網絡

  • -類文件的結構檢查
  • -語義檢驗,是否符合JAVA語言規範
  • -字節碼驗證
  • -二進制兼容性的驗證,如jdk1.5生成的.class文件和jdk1.6生成的.class文件可能存在兼容性問題

2.準備:爲類的靜態變量分配內存,並初始化其值爲默認值。
3.解析:將類中的符號引用轉換直接引用數據結構

  • 符號引用
  • 直接引用

3.3初始化:爲類的靜態變量賦予正確的初始值

 

4.類的卸載

(還在學習中...)學習

相關文章
相關標籤/搜索