《Java高併發編程詳解-多線程架構與設計》Java Classloader

摘自《Java高併發編程詳解-多線程架構與設計》第九章 p144-p157
Java語言規範

重點:

  1. 連接-準備階段爲靜態變量賦初值,初始化階段爲靜態變量賦代碼值
  2. 引起初始化階段的6種情況(主動引用),靜態變量/方法,new,反射,子類引起父類。以及被動引用,如靜態常量。其值opy到被引用的類。
  3. 類加載的三個階段
  4. 靜態代碼塊可以對後面的靜態變量賦值,但不能訪問。
  5. clinit線程安全

1.類加載的三個過程-簡述

  1. 加載階段
    查找並加載class文件
    loadClass from somewhere -> getClassBytes and defineClass->return Class
    常見異常:ClassNotFoundException,NoClassDefFoundError

  2. 連接階段
    a. 驗證
    確保類文件正確性。如class版本,魔數 CAFEBABE
    b. 準備-賦初始值
    爲類的靜態變量 分配內存,初始化【默認值】。
    c. 解析
    將類中符號引用轉爲直接引用。
    如引用了其他類, 則其他類先要經歷類的所有加載過程。

  3. 初始化階段 <clinit>()-賦代碼值
    class initailze爲類的靜態變量賦予正確的值(代碼編寫時指定的值)

2. 類的主動使用和被動使用

JVM虛擬機規定,類和接口被java程序首次主動使用纔會對其進行初始化。

主動使用的場景-new,反射,使用靜態部分,子導致父初始化

  1. new
  2. 訪問類的靜態變量
  3. 訪問類的靜態方法
  4. 對類進行反射操作 。 如 Class.forName(“xx”); 參考java.sql.driver初始化驅動時調用DriverManager註冊driver。
  5. 初始化子類導致父類的初始化
    同理, 調用子類的靜態變量會導致父類的初始化。

在這裏插入圖片描述
6. 啓動類:執行main鎖在的類會導致該類的初始化

在這裏插入圖片描述

除了上述6種,其他的動成爲被動使用,不會導致類的【加載】和【初始化】。

在這裏插入圖片描述

被動使用

  1. 引用類的靜態常量
    ps:靜態常量會在編譯期間被計算出來copy到其他類,可使用jstack查看class文件

  2. 聲明數組

3. 類的加載過程詳解

例子
在這裏插入圖片描述

在這裏插入圖片描述

3.1 類的加載階段

關鍵:1.得到class對應的二進制流(不限方式)2.defineClass

類的加載最終產物是堆內存中的class對象,對於同一個classLoader,不管加載多少次,對應到堆內存中的class是同一個(from cache)。
所以可以使用不同的classLoader加載同名的不同類

虛擬機規範規定類的加載是通過全限定名(包名+類名)來獲取二進制數據流。
調用loadClass->findClass->getClassBytes+defineClass

常見的是class二進制文件形式,但可以是以下:

  1. 運行時動態生成,如ASM ,jdk動態代理,CGLIB
  2. 網絡獲取
  3. 讀取zip獲得類的二進制字節流,如war,jar。
    war,jar使用的是和zip一樣的壓縮算法。
  4. 將類的二進制文件儲存在數據庫的BLOB字段類型中。
  5. 運行時生成class文件,並動態加載,如Thrift/AVRO可以在運行時將schema文件生成對應的class文件再加載。

3.2 類的連接階段

驗證

文件格式:確保類文件正確性。如class版本,魔數 CAFEBABE,MD5比對(class末尾)等。

元數據:確保class符合jvm規範。語義驗證。

字節碼:…
符號引用:…

準備

爲類的靜態變量 分配內存,初始化默認值。
如 static int a = 10; 在【準備階段】a是0而不是10。
如final static int b = 10; 注意,final static變量是【被動引用】,在編譯期間即直接賦予了10;
在這裏插入圖片描述

在這裏插入圖片描述

解析

將類中符號引用轉爲直接引用。
在常量池中尋找類、接口、字段、方法的符號引用,將其替換成直接引用。
在這裏插入圖片描述

初始化

在這裏插入圖片描述
()保證順序,對後面的靜態變量只能賦值不能訪問
在這裏插入圖片描述

類加載過程實例剖析

在這裏插入圖片描述

發佈於2019年7月14日 20:24:54

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章