JVM類載入器及Java類的生命週期

來源:互聯網
上載者:User

標籤:nbsp   sys   scl   https   實現   請求   emc   就是   異常   

預定義類載入器(三種)

啟動(Bootstrap)類載入器:
  是用本地代碼實現的類裝入器,它負責將<Java_Runtime_Home>/lib下面的類庫載入到記憶體中(比如rt.jar)。
由於引導類載入器涉及到虛擬機器本地實現細節,開發人員無法直接擷取到啟動類載入器的引用,所以不允許直接通過引用進行操作。
擴充擴充(Extension)類載入器:
  是由 Sun 的 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)實現的。它負責將< Java_Runtime_Home >/lib/ext或者由系統變數java.ext.dir指定位置中的類庫載入到記憶體中。開發人員可以直接使用標準擴充類載入器。
系統(System)類載入器:

  是由 Sun 的 AppClassLoader(sun.misc.Launcher$AppClassLoader)實現的。它負責將系統類別路徑(CLASSPATH)中指定的類庫載入到記憶體中。開發人員可以直接使用系統類別載入器。

雙親委派機制:
  某個特定的類載入器在接到載入類的請求時,首先將載入任務委託給父類載入器,依次遞迴,如果父類載入器可以完成類載入任務,就成功返回;只有父類載入器無法完成此載入任務時,才自己去載入。這是一種代理方式。

雙親委派意義:
  系統類別防止記憶體中出現多份同樣的位元組碼
  保證Java程式安全穩定運行

線程上下文類載入器(特殊):
  破壞了“雙親委派模型”,可以在執行線程中拋棄雙親委派載入鏈模式,使程式可以逆向使用類載入器。
類 java.lang.Thread中的方法 getContextClassLoader()和 setContextClassLoader(ClassLoader cl)用來擷取和設定線程的上下文類載入器。
如果沒有通過 setContextClassLoader(ClassLoader cl)方法進行設定的話,線程將繼承其父線程的上下文類載入器。Java 應用啟動並執行初始線程的上下文類載入器是系統類別載入器。線上程中啟動並執行代碼可以通過此類載入器來載入類和資源。

1.當高層提供了統一介面讓低層去實現,同時又要是在高層載入(或執行個體化)低層的類時,必須通過線程上下文類載入器來協助高層的ClassLoader找到並載入該類。
2.當使用本類託管類載入,然而載入本類的ClassLoader未知時,為了隔離不同的調用者,可以取調用者各自的線程上下文類載入器代為託管。

 

幾點問題:

  啟動(Bootstrap)類載入器它用來載入 Java 的核心庫,是用原生代碼來實現的,並不繼承自 java.lang.ClassLoader。

  JAVA 虛擬機器是如何判定兩個 Java 類是相同的?

  JAVA 虛擬機器不僅要看類的全名是否相同,還要看載入此類的類載入器是否一樣。只有兩者都相同的情況,才認為兩個類是相同的。即便是同樣的位元組代碼,被不同的類載入器載入之後所得到的類,也是不同的。

eg:

public void testClassIdentity() {    String classDataRootPath = "C:\\workspace\\Classloader\\classData";    FileSystemClassLoader fscl1 = new FileSystemClassLoader(classDataRootPath);    FileSystemClassLoader fscl2 = new FileSystemClassLoader(classDataRootPath);    String className = "com.example.Sample";       try {        Class<?> class1 = fscl1.loadClass(className);        Object obj1 = class1.newInstance();        Class<?> class2 = fscl2.loadClass(className);        Object obj2 = class2.newInstance();        Method setSampleMethod = class1.getMethod("setSample", java.lang.Object.class);        setSampleMethod.invoke(obj1, obj2);    } catch (Exception e) {        e.printStackTrace();    } }

  代碼中使用了類 FileSystemClassLoader的兩個不同執行個體來分別載入類 com.example.Sample,得到了兩個不同的 java.lang.Class的執行個體,接著通過 newInstance()方法分別產生了兩個類的對象 obj1和 obj2,最後通過 Java 的反射 API 在對象 obj1上調用方法 setSample,試圖把對象 obj2賦值給 obj1內部的 instance對象

運行結果
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at classloader.ClassIdentity.testClassIdentity(ClassIdentity.java:26)
at classloader.ClassIdentity.main(ClassIdentity.java:9)
Caused by: java.lang.ClassCastException: com.example.Sample
cannot be cast to com.example.Sample
at com.example.Sample.setSample(Sample.java:7)
... 6 more

  給出的運行結果可以看到,運行時拋出了 java.lang.ClassCastException異常。雖然兩個對象 obj1和 obj2的類的名字相同,但是這兩個類是由不同的類載入器執行個體來載入的,因此不被 JAVA 虛擬機器認為是相同的。

 

Java類的生命週期:

  類從被載入到虛擬機器記憶體中開始,到卸載出記憶體為止,它的整個生命週期包括:載入(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸載(Unloading)7個階段。其中準備、驗證、解析3個部分統稱為串連(Linking)。

載入(Loading):

  就是將源檔案的class檔案找到類的資訊將其載入到方法區中,
然後在堆區中執行個體化一個java.lang.Class對象,作為方法區中這個類的資訊的入口。

串連(Linking):
  驗證:確定該類是否符合java語言的規範,有沒有屬性和行為的重複,繼承是否合理,總之,就是保證jvm能夠執行
  準備:主要做的就是為由static修飾的成員變數分配記憶體,並設定預設的初始值
    (1.八種基礎資料型別 (Elementary Data Type)預設的初始值是0
       2.參考型別預設的初始值是null
       3.有static final修飾的會直接賦值,例如:static final int x=10;則預設就是10.)
  解析:這一階段的任務就是把常量池中的符號引用轉換為直接引用,說白了就是jvm會將所有的類或介面名、欄位名、方法名轉換為具體的記憶體位址。

初始化(Initialization)
  這個階段就是將靜態變數(類變數)賦值的過程,即只有static修飾的才能被初始化,執行的順序就是:
父類靜態域或著靜態代碼塊,然後是子類靜態域或者子類靜態代碼塊

使用(Using)
  在類的使用過程中依然存在三步:對象執行個體化、垃圾收集、對象終結

卸載(Unloading)
  類的生命週期走到了最後一步,程式中不再有該類的引用,該類也就會被JVM執行記憶體回收,從此生命結束。

參考文章:

https://www.ibm.com/developerworks/cn/java/j-lo-classloader/

http://blog.csdn.net/yangcheng33/article/details/52631940

 

JVM類載入器及Java類的生命週期

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.