1. 程式人生 > >JVM學習之Java類載入

JVM學習之Java類載入

Java類載入

我們知道,java原始碼(*.java)不能直接執行,我們需要通過java編譯器javac.exe將原始碼編譯為java字解碼檔案(*.class),然後再通過java.exe在JVM中解釋此程式。

一、Java程式執行流程
這裡寫圖片描述
二、類載入器(ClassLoader)
這裡寫圖片描述
類載入器有以下幾種型別:

  • 1、啟動類載入器(Bootstrap ClassLoader):該ClassLoader是jvm在啟動時建立的,用於載入 $JAVA_HOME/jre/lib下面的類庫(或者通過引數-Xbootclasspath指定)。由於引導類載入器涉及到虛擬機器本地實現細節,開發者無法直接獲取到啟動類載入器的引用,所以不能直接通過引用進行操作。

  • 2、擴充套件類載入器(ExtClassLoader):該ClassLoader是在sun.misc.Launcher裡作為一個內部類ExtClassLoader定義的(即 sun.misc.Launcher.ExtClassLoader),ExtClassLoader會載入 $JAVA_HOME/jre/lib/ext下的類庫(或者通過引數-Djava.ext.dirs指定)。

  • 3、 應用程式類載入器(AppClassLoader):應用程式類載入器,該ClassLoader同樣是在sun.misc.Launcher裡作為一個內部類AppClassLoader定義的(即 sun.misc.Launcher.AppClassLoader),AppClassLoader會載入java環境變數CLASSPATH所指定的路徑下的類庫,而CLASSPATH所指定的路徑可以通過System.getProperty(“java.class.path”)獲取;當然,該變數也可以覆蓋,可以使用引數-cp,例如:java -cp 路徑 (可以指定要執行的class目錄)。

  • 4、自定義類載入器(CustomClassLoader):該ClassLoader是指我們自定義的ClassLoader,比如tomcat的StandardClassLoader屬於這一類;當然,大部分情況下使用AppClassLoader就足夠了。

三、雙親委派載入機制

  • 1、類載入原始碼:
protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        synchronized (getClassLoadingLock(name)) {
            // First, check if the class has already been loaded
Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { // If still not found, then invoke findClass in order // to find the class. long t1 = System.nanoTime(); c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }
  • 2、載入過程:
    • 1)、首先驗證這個類是否已經載入過,如果載入過直接返回。
    • 2)、如果沒有載入過,再去判斷是否有父載入器。如果有就遞迴呼叫父載入器驗證是否載入此類。
    • 3)、如果沒有父類載入器則呼叫啟動類載入器(Bootstrap ClassLoader)載入此類。
    • 4)、如果啟動類載入器(Bootstrap ClassLoader)也未找到此類,則會呼叫findClass(name)進行載入。
    • 5)、如果findClass(name)還未找到就拋ClassNotFoundException異常。

四、雙親委派載入機制好處

  • 1、避免類被重複載入
  • 2、安全:假如自定義一個Java中已經有的類,初始化的時候JVM會先委託BootStrapClassLoader載入JDK中已有的類,而自定義的類永遠都不會被載入。

五、類載入詳細過程
這裡寫圖片描述

  • 1、載入:類載入階段就是由類載入器負責根據一個類的全限定名來讀取此類的二進位制位元組流到JVM內部,並存儲在執行時記憶體區的方法區,然後將其轉換為一個與目標型別對應的java.lang.Class物件例項(Java虛擬機器規範並沒有明確要求一定要儲存在堆區中,只是hotspot選擇將Class物件儲存在方法區中),這個Class物件在日後就會作為方法區中該類的各種資料的訪問入口。
  • 2、連線:是將載入到JVM中的二進位制位元組流的類資料資訊合併到JVM的執行時狀態中,經由驗證、準備、解析三個階段。
    • 驗證:驗證類資料資訊是否符合JVM規範,是否是一個有效的位元組碼檔案,驗證內容涵蓋了類資料資訊的格式驗證、語義分析、操作驗證等
    • 準備:為類中的所有靜態變數分配記憶體空間,併為其設定一個初始值(由於還沒有產生物件,例項變數將不再此操作範圍內)。
    • 解析:將常量池中所有的符號引用轉為直接引用(得到類或者欄位、方法在記憶體中的指標或者偏移量,以便直接呼叫該方法)。這個階段可以在初始化之後再執行。
  • 3、初始化:對類記憶體資料進行初始化賦值等。
  • 4、使用:…
  • 5、解除安裝:類使用完成之後,根據其情況進行GC操作。

六、類初始化順序

Foo.java

public class Foo {

    public Foo() {
        System.out.println("Foo.constructor...");
    }

    static {
        System.out.println("Foo.static...");
    }

    {
        System.out.println("Foo...");
    }
}

Son.java

public class Son extends Foo {

    public Son() {
        System.out.println("Son.constructor...");
    }

    static {
        System.out.println("Son.static...");
    }

    {
        System.out.println("Son...");
    }

    public static void main(String[] args) {
        new Son();
    }
}

控制檯

Foo.static...
Son.static...
Foo...
Foo.constructor...
Son...
Son.constructor...

初始化說明:

  • 1、父類靜態資源
  • 2、子類靜態資源
  • 3、父類非靜態資源
  • 4、父類建構函式
  • 5、子類非靜態資源
  • 6、子類建構函式

相關推薦

JVM學習Java載入

Java類載入 我們知道,java原始碼(*.java)不能直接執行,我們需要通過java編譯器javac.exe將原始碼編譯為java字解碼檔案(*.class),然後再通過java.exe在JVM中解釋此程式。 一、Java程式執行流程 二、類載入

jvm系列學習--Java的初始化順序

parent main方法 println () 類成員 -- sys div 開始 本文主要演示Java類的初始化順序 初始化順序 對於靜態變量、靜態初始化塊、變量、初始化塊、構造器,它們的初始化順序依次是(靜態變量、靜態初始化塊)>(變量、初始化塊)>構造器

jvmjava載入機制和載入器(ClassLoader)的詳解

     當程式主動使用某個類時,如果該類還未被載入到記憶體中,則JVM會通過載入、連線、初始化3個步驟來對該類進行初始化。如果沒有意外,JVM將會連續完成3個步驟,所以有時也把這個3個步驟統稱為類載入或類初始化。                             

JVM學習java記憶體模型

JVM學習之java記憶體模型 以下blog內容來自《深入理解Java虛擬機器_JVM高階特性與最佳實踐》感謝作者!! java虛擬機器規範定義了一種java記憶體模型(JMM)來遮蔽不同硬體和作業系統的差異,達到跨平臺執行效果,記憶體模型的定義一個宗旨就是併發記憶體訪問操作不會產生

JVM學習java執行緒實現&排程和狀態轉換

以下blog內容來自《深入理解Java虛擬機器_JVM高階特性與最佳實踐》感謝作者! 1 謹慎使用java 多執行緒   如何提升效率:      使用java時推薦利用多執行緒處理一些操作絕大多數情況下確實能提高效率,提高效率的原理

jvm學習java記憶體區域

java虛擬機器在執行java程式的過程中會把它所管理的記憶體劃分為若干不同區域:有些是依賴使用者執行緒的啟動和結束而建立和銷燬的,有的則是隨著虛擬機器程序的啟動而存在。 執行緒共享區域:方法區 、堆。 執行緒隔離(各個執行緒獨有區域)虛擬機器棧、本地方法棧、程式計數器。  

JVM學習java執行緒實現&排程和狀態轉換

1 謹慎使用java 多執行緒   如何提升效率:      使用java時推薦利用多執行緒處理一些操作絕大多數情況下確實能提高效率,提高效率的原理在哪裡呢,為什麼說絕大多說情況呢。        在CPU單核時代,我們知道某一時刻工作的執行緒只能是一條,那多執行緒為什

JVM學習筆記(七)載入機制-載入的時機、過程

前言   Java虛擬機器類載入過程是把Class類檔案載入到記憶體,並對Class檔案中的資料進行校驗、轉換解析和初始化,最終形成可以被虛擬機器直接使用的java型別的過程。   與那些在編譯時需要進行連線工作的語言不同,在java語言裡,型別的載

jvm系列學習--Java加載機制

任務 字節 修飾符 https 完整 自定義類加載器 字節流 由於 字節碼 轉載:https://segmentfault.com/a/1190000004597758 本文主要講述Java類的加載機制,主要包括類加載器、加載過程、初始化時機。 一、類加載器 1、Clas

Java學習抽象

進行 java 創建對象 抽象類 ava abs 函數 創建 bsp java抽象類的使用 當多個類中出現相同功能,但是功能主體不同,這是可以進行向上抽取。這時,只抽取功能定義,而不抽取功能主體。抽象:看不懂。抽象類的特點:1,抽象方法一定在抽象類中。2,抽象方法和抽象類都

java面向對象學習——java中的修飾符、成員變量修飾符、方法修飾符

16px 實例化 同時 pan 相同 nbsp 激活 fin ati 類修飾符: public(訪問控制符)——>將一個類聲明為公共類,他可以被任何對象訪問,一個程序的主類必須是公共類。abstract——>將一個類聲明為抽象類,沒有實現的方法,需要子類提供方法

小白的java學習路 “ 和對象”

之路 抽象 AS 類和對象 可維護 屬性和方法 style “.” 信息 一.※ 萬物皆對象 二.對象的兩個特征: 屬性:對象具有的各種特征 方法:對象執行的操作 對象:用來描述客觀事物的一個實體,由一組屬性和方法構成 三.

Java開發學習java基本數據

培訓班 otto oat style 簡單 lean 實用 類型 str 數據類型是每個編程語言必不可少的基礎知識,也是必須要掌握的技能,很多人知識簡單的進行理解,並沒有很系統的進行知識的梳理,以下是對java語言的內置數據類型匯總:  Java語言有8種基本類型。6種數字

Java學習JOptionPane

visible 對話 用戶 運行 pan test ati 分享圖片 類方法 在圖形用戶界面(GUI)環境中,大體上有兩種類型的窗體: 框架窗體(frame window)和對話窗體(dialog window)。 在Java中,我們使用JFrame對象作為框架窗體,使用J

JVM——Java載入機制

class Singleton{ private static Singleton singleton = new Singleton(); public static int value1; public static int valu

JAVA 載入機制學習筆記

JAVA 類生命週期     如上圖所示,Java類的生命週期如圖所示,分別為載入、驗證、準備、解析、初始化、使用、解除安裝。其中驗證、準備、解析這三個步驟統稱為連結。   載入:JVM根據全限定名來獲取一段二進位制位元組流,將二進位制流轉化為方法區的執行時資料結構,在記憶體中生成一個代表

Java基礎ClassLoader載入器簡介

classloader簡介 1 classloader層次結構(父子關係) Bootstrap(ClassLoader) ExtClassLoader AppClassLoader XXXClassLoader 詳見程

jvm系列(一):java載入機制

1、什麼是類的載入 類的載入指的是將類的.class檔案中的二進位制資料讀入到記憶體中,將其放在執行時資料區的方法區內,然後在堆區建立一個java.lang.Class物件,用來封裝類在方法區內的資料結構。類的載入的最終產品是位於堆區中的Class物件,Clas

Java載入過程 ——Thinking in Java學習筆記(六)

java中一個類從被載入開始,一直到被銷燬為止,類的整個生命週期包括:載入、驗證、準備、解析、初始化、使用和解除安裝七個階段。 其中,類載入過程包括載入、驗證、準備、解析、初始化,其中,驗證、準備、解析又被合稱為連線過程。 1、載入階段 載入過程的主要工作有:

2018年11月13日Java學習包裝,裝箱與拆箱,

1.將八種基本資料型別定義相應的引用型別—包裝類 這樣做的好處就是可以呼叫類的方法了。 2.裝箱與拆箱 裝箱 int i = 500; Integer t = new Integer(i); 拆箱 boolean b = bObj.booleanValue