1. 程式人生 > >JVM系列-類載入機制

JVM系列-類載入機制

    簡介


  在java中,類的宣告週期總共分為以下幾種: 載入(Loading),驗證(Verification),準備(Preparation),解析(Analysis),

初始化(Initialization),使用(Using),解除安裝(Unloading)。其中,驗證,準備,解析統稱為連線(Linking)如圖

一、載入:

    在載入階段,JVM需要完成以下準備:

     通過一個類的全限定名來獲取定義此類的二進位制位元組流(並非要從class檔案獲取,也可從jar或war中讀取,也可以在執行時動態生成,還可以編譯jsp時獲取)

二、驗證:

  驗證是為了確保class檔案中的位元組流包含的資訊符合JVM的要求,並且不會危害JVM自身的安全,驗證大致分為四中方法:

  1. 檔案格式驗證: 驗證位元組流是否符合class檔案的規範,例:主次版本號是否在當前JVM範圍內,常量池中的常量是否有不被支援的型別
  2. 元資料驗證: 對位元組碼描述的資訊進行語義分析(javac編譯階段的語義分析),以保證其描述資訊符合java語言規範要求
  3. 位元組碼驗證: 通過資料流和控制流分析,確保程式是合法的,符合邏輯的
  4. 符號引用驗證: 確保解析動作能正確執行

  PS: 驗證階段是很重要的,但不是必須的,如果所引用的類已經經過了反覆校驗,可以使用 -Xverifynone引數來關閉一些驗證措施,

           用來縮短JVM載入時間

三、準備:

   準備階段是正式為類變數分配記憶體並設定類變數初始值的階段,這些變數所使用的記憶體都將在方法區中進行分配。

這裡進行的記憶體分配僅包含類變數(被static修飾的變數),不包含例項變數(區別見末尾)。

   初始值例: public static int value = 123;

    如上宣告的話value的值會在準備階段後為0而不是123。因為此時尚未執行任何java方法,value被賦值123是程式被編譯後存放於

類構造器<client>中。但是還有一種特殊情況:

初始值例:public static final int value = 123;

   這時在準備階段後會為value生成ConstantValue屬性,賦值為123而非0。

 類變數(靜態變數):

  1. 在類中被static修飾,並且必須在構造方法和語句塊之外
  2. 無論一個類建立了多少變數,類只擁有類變數的一份拷貝
  3. 類變數在程式開始是建立,程式結束時銷燬
  4. 靜態變數儲存在靜態儲存區,經常被宣告為常量
  5. 靜態變數可以通過className,VariableName訪問到

例項變數:

  1. 宣告在類中,不在方法,構造方法,語句塊之內
  2. 當一個物件被例項化之後,每個例項變數的值就跟著確定
  3. 例項變數在物件建立是建立,物件銷燬時銷燬
  4. 例項變數的值應至少被一個方法,構造方法或語句塊引用,使得外部可以用這些方法獲取例項變數的值
  5. 例項變數可以直接通過變數名訪問,但在靜態方法和其它類中,應使用完全限定名:ObjectReference.VariableName

未完待續