jvm(2)---類加載機制

1.類加載:類加載器將class文件加載到虛擬機的內存
加載:在硬盤上查找並經過IO讀入字節碼文件
鏈接:執行校驗、準備、解析步驟
校驗:校驗字節碼文件的正確性
準備:給類的靜態變量分配內存,並賦予默認值
解析:類裝載器裝入類所引用的其餘全部類
初始化:對類的靜態變量初始化爲指定的值,執行靜態代碼塊java

 

2.類加載器spring

啓動類加載器(BootstrapClassLoader):負責加載JRE的核心類庫,如jre目標下的rt.jar,charsets.jar等
擴展類加載器(ExtensionClassLoader):負責加載JRE擴展目錄ext中JAR類包
系統類加載器(ApplicationClassLoader):負責加載ClassPath路徑下的類包
用戶自定義加載器(CustomClassLoader):負責加載用戶自定義路徑下的類包jvm

執行以下代碼,查看對應的類加載器:ide

package com.nijunyang.spring;


import com.sun.crypto.provider.BlowfishCipher;

/**
 * @author: create by nijunyang
 * @date:2019/6/16
 */
public class ClassLoaderTest {
    public static void main(String[] args)
    {
        System.out.println(String.class.getClassLoader());
        System.out.println(BlowfishCipher.class.getClassLoader().getClass().getName());
        System.out.println(ClassLoaderTest.class.getClassLoader().getClass().getName());
        System.out.println(ClassLoader.getSystemClassLoader().getClass().getName());
    }
}

 

   -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------spa

能夠看到String的類加載器null,由於String是在java核心包rt.jar裏面這裏面東西是由啓動類加載器加載的,而啓動類加載器是由C/C++實現的,根本不在JDK裏面。
BlowfishCipher的類加載器是ExtClassLoader,而這個類正是Jre擴展目錄ext中jar包所在的類
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

3.類加載機制--全盤委託和雙親委派機制3d

全盤委託:當一個ClassLoader加載一個類時,除非顯示的使用另外一個ClassLoader,該類所依賴和引用的類也由這個ClassLoader載入,好比說A依賴B,那麼B的加載器和A的加載器同樣。對象

雙親委派:指先委託父類加載器尋找目標類,在找不到的狀況下在本身的路徑中查找並載入目標類,感受說父類加載器不是很合適,由於沒有這一層關係,感受更像是上下級關係。委託上級加載器尋找目標類。blog

雙親委派的好處:ip

1.避免類重複加載,上級加載了,下級就不須要再加載內存

2.由於核心API都有固定的加載器,能夠防止核心庫被篡改: 自定義一個String類,一樣在java.lang包下,運行代碼會發現啓動報錯,實際加載的java.lang.String類並無main方法,說明實際加載的String類並非咱們自定義的String類,而是由於雙親委派機制,往上委託到啓動類加載器,去加載rt.jar裏面的String類

 

4.類加載過程

實際上jvm對class文件是按需加載的,須要的時候才加載(運行時動態加載),並不是一次所有加載進去,jvm啓動參數加上:-verbose:class 查看類加載

package com.nijunyang.spring;


/**
 * @author: create by nijunyang
 * @date:2019/6/16
 */
public class ClassLoaderTest {
    static {
        System.out.println("靜態塊執行");
    }
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(3000);
        System.out.println(System.currentTimeMillis());
        new A();
        System.out.println("A對象建立完畢");
        new B();
    }
}

 

從結果中咱們能夠看到

1.從本地/E:/IdeaProject/tuling/spring/target/classes/下面去加載當前運行類ClassLoaderTest.class文件

2.初始化類,執行靜態代碼塊

3.main方法運行,睡了5s以後打印當前時間,當咱們new A的時候纔去本地加載A.class文件到內存,再實例化A

4.A建立完畢以後,再去加載B.class,完成B的初始化

相關文章
相關標籤/搜索