1. 程式人生 > >JVM的類載入機制

JVM的類載入機制

引用官方:

虛擬機器把描述類的資料從Class 檔案載入到記憶體,並對資料進行校驗、轉換解析和初始化,最終形成可以被虛擬機器直接使用的Java型別叫做虛擬機器的類載入機制。

在詳細介紹載入的每隔步驟之前,先來了解下總體步驟:

  • 載入
  • 驗證
  • 準備
  • 解析
  • 初始化
  • 使用
  • 解除安裝

在這裡插入圖片描述

從上面我們可以看出,一個類從載入到解除安裝總共會經歷七個步驟。其中,驗證、準備、解析三個步驟又被統稱為連線。

下面開始詳細分析介紹這七個步驟中的每一步:

什麼時候會觸發類的初始化動作?

1、new、putstatic、getstatic、invokestatic 4條位元組碼指令,如果一個類還沒有初始化則會觸發初始化操作(載入動作會發生)。在java程式碼中對應的便是:new Object(),使用某個類的靜態屬性(又叫類屬性),使用某個類的靜態方法。

2、使用java.lang.reflect方法的時候

3、初始化一個類的時候,發現其父類還沒有進行初始化

4、當虛擬機器啟動的時候,使用者指定的執行的主類(main()方法)

在虛擬機器規範中,把類的引用分為了主動引用和被動引用,以上四種方式被稱作主動引用,同時有且僅有以上四種方式被稱為主動引用。下面為大家介紹幾種被動引用的列子:

  • 子類引用父類的靜態欄位不會觸發子類的初始化
public  class father {
     static {
         Syso("class father 被初始化辣------!");
     }
     //這裡需要區分 : public static final int value = 100的區別(後面會講到)
     public static int  value = 100;
}

public  class son extends father {
    static {
        Syso("class son 被初始化辣-------!");
    }
}


public class main {
     public static void main(String [] args ) {
          Syso(son.value);
     }
}
  • 通過陣列定義來引用類不會觸發該類的初始化
//這裡繼續使用上面定義的son 類

public class main{
     public static void main(String[] args) {
        son[]  sons = new son[10];
   }
}

執行上面這段程式碼,我們會發現並沒有 "class son 被初始化辣!"這段話輸出,說明son這個類沒有被初始化,這是為什麼呢?
原因是:

虛擬機器在這裡觸發了另一個類的初始化,他就是:Lorg.fenixsoft.classloading.son .

這個類是由虛擬機器直接建立,並繼承與Object類,會由指令 newarray觸發

  • 引用類常量不會觸發常量類的初始化
class Constclass {
     static{
         Syso("Constclass 初始化辣!")
     }

    public static final String value = "hello 世界你好!!";
}


class Main{
       public void main(String[]  args) {
            Syso(Constclass.value);
       }
}

執行上面的餓程式碼,我們不會看到 "Constclass 初始化辣!"這行文字的輸出。是因為在編譯階段將常量類Constclass的常量value儲存到了Main類的常量池中。

上面嘮叨了一堆,為大家介紹了類載入會經理哪些過程,以及在什麼時候會觸發類的初始化。以及在實際使用中常常會被我們忽略的被動初始化情況。接下來為大家詳細介類載入過程中每一步的詳情。

載入

在載入階段,jvm主要會做三件事:

  1. 根據類的全限定名(在反射的時候會用到Class.forName(“類的全限定名”))來獲取定義此類的二進位制位元組流檔案
  2. 將這個位元組流所代表的靜態儲存結構轉化為方法區的執行時資料結構
  3. 在堆區中生成一個代表這個類結構的 java.lang.Class 物件,作為方法區這些資料的訪問入口。

在整個類載入過程中,載入階段是可控性最強的,使用者可以自定義類載入器來完成一些特別的事情。在代理模式中也主要是在這個階段做文章。(稍後會講到類載入器知識點,會在另一篇筆記中探討關於代理的知識點)

驗證

這個階段的主要目的是為了保證Class檔案的位元組流中包含的資訊符合當前虛擬機器的要求。不同虛擬機器的驗證規則和驗證步驟會由些許不同,但大致主要分為以下幾個步驟:

  1. 檔案格式驗證(這個階段是為了保證位元組流能夠被正確的解析並存儲於方法區中,經過這個階段的驗證,位元組流才會進如記憶體的方法區中進行儲存)
  2. 元資料驗證(主要工作室:位元組碼描述的資訊進行語義分析,目的:對類的元資料資訊進行語義校驗)
  3. 位元組碼驗證(主要工作是對資料流和控制流進行分析,這部分的驗證主要是針對方法體進行)
  4. 符號引用驗證(發生在虛擬機器將符號引用轉換為直接引用的階段,也就是類載入的解析階段)

準備

在這個階段將會為類變數分配類存和設定初始化值,這些記憶體會被分配在方法區中(這裡需要搞清楚類變數和實化變數,同時,這裡所說的初始化值是指資料型別的零值)。

問題1

public static int value = 123;

請問:在準備階段,value的值等於多少?
答案是:0
為什麼呢?
是因為在這個時候還未執行任何java方法,把value的值設定成123的putstatic指令是在程式編譯後,存放於類構造器中,value =123在類的初始化階段才會執行。

問題2

public static final value =123;

請問:在準備階段,value的值等於多少?
答案是:123

解析

解析屬於類載入的第四個階段,在這個階段,主要的目的是將常量池中的符號引用轉換成直接引用。

在這個階段,我們需要搞清楚幾個問題。

問題1:符號引用和直接引用的區別?

符號引用:用一組符號來表示引用的目標。符號引用與記憶體佈局無關,引用的目標並不一定載入到記憶體中去了。

直接引用:直接引用可以是直接指向目標的指標或者位置偏移量,或者是間接指向目標的控制代碼。直接引用與虛擬機器的記憶體佈局有關,如果有了直接引用,那引用的目標必定已經存在於記憶體佈局當中。

問題2:解析的動作主要針對誰?

一般解析主要針對類、介面、欄位、類方法。

初始化

初始化是類載入的最後一個階段,也是在初始化階段才是真正開始執行java程式碼(位元組碼檔案)
在準備階段,執行過一次類變數賦值操作(記住這時的賦值特點)。在初始化階段,會真正按照程式設計師的計劃去執行賦值操作,初始化階段又叫做執行類構造器()方法的過程。
在這裡有幾個點需要注意:

  • 這個方法由編譯器自動收集類變數的賦值操作和類中的靜態語句塊中的語句合併而成的。
  • 編譯器可以保證一個類的()方法在多執行緒環境下面可以被正確的加鎖執行。所以我們需要注意,不能再類初始化方法()方法中執行耗時操作。如下程式碼便是一個錯誤的寫法:
class MyClass {
    static {
        while(true) {
            Syso(“模擬耗時操作---------”);
       }
   }
}

相關推薦

JVM 載入機制詳解

原文出處: ziwenxie 如下圖所示,JVM類載入機制分為五個部分:載入,驗證,準備,解析,初始化,下面我們就分別來看一下這五個過程。 載入 載入是類載入過程中的一個階段,這個階段會在記憶體中生成一個代表這個類的java.lang.Class物件,作為方法區這個類的

JVM載入機制—結合程式碼分析

《深入理解Java虛擬機器》學習筆記 首先看下面的兩個類 對於被主動引用的類,執行類載入操作,根據給定的全限定名獲取這個類的二進位制位元組流(不一定是class檔案,網路、動態代理等方式也會)並將二進位制按虛擬機器要求的格式儲存在方法區(HotSpot儲存用於訪問方法

JVM(二):JVM載入機制

如下圖所示,JVM類載入機制分為五個部分:載入,驗證,準備,解析,初始化,下面我們就分別來看一下這五個過程。   載入 載入是類載入過程中的一個階段,這個階段會在記憶體中生成一個代表這個類的java.lang.Class物件,作為方法區這個類的各種資料的入口。注意這裡不一

[JVM]載入機制及反射

一、Java類載入機制 1.概述        Class檔案由類裝載器裝載後,在JVM中將形成一份描述Class結構的元資訊物件,通過該元資訊物件可以獲知Class的結構資訊:如建構函式,屬性和方法等,Java允許使用者藉由這個Class相關的元資訊物件間接呼叫Clas

JVM:載入機制

前言 JAVA虛擬機器中的類載入機制非常重要,在關於JVM的面試中經常問到,因此今天整理一下相關的知識點,一方面為之後的面試做準備,另一個方法也是擴充套件一下知識面。 類的生命週期 關於類的生命週期,直接上圖看下。 類從載入進虛擬機器記憶體,到從虛擬機器解除安裝的整個生命過程包

JVM 載入機制:編譯器常量與初始化

1. 前言 最近在研究JVM虛擬機器類載入機制的時候,我們瞭解到了類載入機制的生命週期以及在準備階段,JVM虛擬機器會對類的靜態變數進行初始化,這個時候只是會將靜態變數初始化為預設的初始值。對靜態變數的定義的初始化值,將會被封裝到clinit()方法中,直到初始化階段進行初始化。但是對於

JVM 載入機制深入淺出

從類被載入到虛擬機器記憶體中開始,到卸御出記憶體為止,它的整個生命週期分為7個階段,載入(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Usi

JVM系列第7講:JVM 載入機制

當 Java 虛擬機器將 Java 原始碼編譯為位元組碼之後,虛擬機器便可以將位元組碼讀取進記憶體,從而進行解析、執行等整個過程,這個過程我們叫:Java 虛擬機器的類載入機制。JVM 虛擬機器執行 class 位元組碼的過程可以分為七個階段:載入、驗證、準備、解析、初始化、使用、解除安裝。 在開始聊之前,先

JVM載入機制詳解(一)JVM載入過程

首先Throws(丟擲)幾個自己學習過程中一直疑惑的問題: 1、什麼是類載入?什麼時候進行類載入? 2、什麼是類初始化?什麼時候進行類初始化? 3、什麼時候會為變數分配記憶體? 4、什麼時候會為變數賦

JVM載入機制

Java虛擬機器類載入過程是把Class類檔案載入到記憶體,並對Class檔案中的資料進行校驗、轉換解析和初始化,最終形成可以被虛擬機器直接使用的java型別的過程。 在載入階段,java虛擬機器需要完成以下3件事: a.通過一個類的全限定名來獲取定義此類的二進位制位元組流

理解JVM(四):JVM載入機制

Class檔案 我們寫的Java程式碼,經過編譯器編譯之後,就成為了.class檔案,從本地機器碼變成了位元組碼。Class檔案是一組以8位位元組為基礎單位的二進位制流,各個資料專案嚴格按照順序緊湊地排列在Class檔案之中,中間沒有新增任何分隔符,這使得整個

深入理解JVM載入機制

深入理解JVM類載入機制 轉載自:https://blog.csdn.net/a724888/article/details/78396462 簡述:虛擬機器把描述類的資料從class檔案載入到記憶體,並對資料進行校驗、轉換解析和初始化,最終形成可以被虛擬機器直接使用的Java型別,這就是虛

jvm 載入機制雙親委託機制

1.ClassLoader分為啟動類載入器(BootStrap ClassLoader)、拓展類載入器(Extension ClassLoader)、應用類載入器(App ClassLoader) 1.1 jvm中ClassLoader會協同工作,就是說在載入

深入JVM載入機制

從ClassLoad開始說起 ClassLoader顧名思義就是我們所常見的類載入器,其作用就是將編譯後的class檔案載入記憶體當中.在應用啟動時,JVM通過ClassLoader載入相關的類到JVM當中.在具體瞭解ClassLoader之前我們先來了解下J

一道面試題搞懂JVM載入機制

有這樣一道面試題: class Singleton{ private static Singleton singleton = new Singleton(); public static int value1; public stat

淺析JVM載入機制

淺析類載入機制 類載入器簡單來說是用來載入 Java 類到 Java 虛擬機器中的。Java 虛擬機器使用 Java 類的方式如下:Java 源程式(.java 檔案)在經過 Java 編譯器編譯之後就被轉換成 Java 位元組程式碼(.class 檔案)。類載入器負責讀

JVM載入機制(ClassLoader)原始碼解析(1)

其實JVM類載入機制,簡單地說就是類管理,也就是我們生成的class檔案。 三個步驟:裝載(load)、連結(link)、解析(Resolve)、還有初始化(Initialize) 關於網上有很多講解載入的方式,和呼叫的方式,還是幾個基本的classLoader,這裡就不在

JVM載入機制詳解(二)載入器與雙親委派模型

1、通過一個類的全限定名(包名與類名)來獲取定義此類的二進位制位元組流(Class檔案)。而獲取的方式,可以通過jar包、war包、網路中獲取、JSP檔案生成等方式。 2、將這個位元組流所代表

深入理解JVM(七)JVM載入機制

7.1JVM類載入機制   虛擬機器把資料從Class檔案載入到記憶體,並且校驗、轉換解析和初始化最終形成可以被虛擬機器使用的Java型別,這就是虛擬機器的類載入機制。 7.2類載入的時機   1.類載入的步驟開始的順序: 載入(Loading) -> 驗證(Veri

圖解JVM載入機制載入過程

0、前言 讀完本文,你將瞭解到: 一、為什麼說Jabalpur語言是跨平臺的 二、Java虛擬機器啟動、載入類過程分析 三、類載入器有哪些?其組織結構是怎樣的? 四、雙親載入模型的邏輯和底層程式碼實現是怎樣的? 五、類載入器與Class<T&