動手試試ClassLoader,直譯器,JIT

天狼42發表於2020-11-30

jvm載入器

載入器的載入器不是父類的關係

雙親委派,又稱做專案,流程,先問最近的,有沒有做過,往上問,最後專案中沒有就自己搞

主要是安全問題,進來個東西,自己幹不過,請求上級支援,再請求支援。層層申請。

雙親委派,跟載入快取的過程很像,先看我這有沒有這個東西,有的話,就載入沒有的話再說

 

引用馬士兵ppt

/**
 * 類載入器4個級別
 * BootstrapClassLoader
 * ExtClassLoader
 * AppClassLoader
 * CustomClassLoader客戶端自定義
 *
 * Launcher是classLoader的啟動類
 */

public class TestClassLoader {
    public static void main(String[] args) throws ClassNotFoundException {
        //BootstrapClassLoader
        System.out.println(String.class.getClassLoader());
        System.out.println(sun.awt.HKSCS.class.getClassLoader());
        //Launcher$ExtClassLoader
        System.out.println(sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader());
        //Launcher$AppClassLoader,我們寫的類都是AppClassLoader載入的
        System.out.println(TestClassLoader.class.getClassLoader());
        System.out.println("-------");
        System.out.println(sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader());
        System.out.println(TestClassLoader.class.getClassLoader().getClass().getClassLoader());
        System.out.println("----------");System.out.println("-------");

        //檢視一個class,通過getParent()方法,他的ClassLoader
        System.out.println(TestClassLoader.class.getClassLoader().getParent().getParent());
        //ExtClassLoader
        System.out.println(TestClassLoader.class.getClassLoader().getParent());
        //sun.misc.Launcher$AppClassLoader@18b4aac2
        System.out.println(TestClassLoader.class.getClassLoader());
        System.out.println("-------");System.out.println("-------");

        //看不同ClassLoader載入了哪些jar包
        System.out.println("BootstrapClassLoader----");
        String bootClassPath = System.getProperty("sun.boot.class.path");
        System.out.println(bootClassPath.replaceAll(";",System.lineSeparator()));

        System.out.println("ExtClassLoader----");
        String var0 = System.getProperty("java.ext.dirs");
        System.out.println(var0.replaceAll(";",System.lineSeparator()));

        System.out.println("AppClassLoader----");
        String var1 = System.getProperty("java.class.path");
        System.out.println(var1.replaceAll(";",System.lineSeparator()));
        System.out.println("-------");System.out.println("-------");

        //自定義ClassCloader,通過LoadClass 熱部署
        Class clazz = TestClassLoader.class.getClassLoader().loadClass("com.example.demo.jvm.TestClassLoader");
        System.out.println(clazz.getName());
    }
    public void hello(){
        System.out.println("hello world  ali");
    }
}
以下是自極客時間的摘抄和總結
 
虛擬機器的好處
  • jvm虛擬機器可以由軟硬體實現。一次編寫,到處執行
  • 託管環境。處理程式碼終得錯誤。能夠處理自動記憶體管理,垃圾回收。
虛擬機器具體是怎樣執行 Java 位元組碼的?
  • 從虛擬機器視角來看,執行 Java 程式碼首先需要將它編譯而成的 class 檔案載入到 Java 虛擬 機中。載入後的 Java 類會被存放於方法區(Method Area)中。實際執行時,虛擬機器會執 行方法區內的程式碼。
 
Java 虛擬機器會將棧細分為面向 Java 方法的 Java 方法棧,面向本地方法(用 C++ 寫的 native 方法)的本地方法棧,以及存放各個執行緒執行位置的 PC 暫存器
進入方法 ->java方法棧 -> 棧幀 ->存放區域性變數,位元組碼的運算元
 
從硬體視角來看,Java 位元組碼無法直接執行。因此,Java 虛擬機器需要將位元組碼翻譯成機器碼。
翻譯過程2種
  • 解釋執行: 逐條將位元組碼翻譯成 機器碼並執行.好處,無需等待編譯(自行車,生物動力)
  • 即時編譯( Just-In-Time compilation,JIT ): 將一個方法中 包含的所有位元組碼編譯成機器碼後再執行。(汽車,物理動力)
不同在於編譯的範圍
 
Java 虛擬機器的執行效率究竟是怎麼樣的?
不常用的用直譯器,小部分熱點程式碼,用jit。
多個jit。 HotSpot 內建了多個即時編譯器:C1、C2 和 Graal。 Graal 是 Java 10 正式引入的實驗性即時編譯器。
 
C1 又叫做 Client 編譯器,面向的是對啟動效能有要求的客戶端 GUI 程式,採用的優化手段相 對簡單,因此編譯時間較短
 
C2 又叫做 Server 編譯器,面向的是對峰值效能有要求的伺服器端程式,採用的優化手段 相對複雜,因此編譯時間較長,但同時生成程式碼的執行效率較高
 
Java 虛擬機器將 執行時記憶體區域劃分為五個部分,分別為方法區、堆、PC 暫存器、Java 方法棧和本地方法棧。

在run中編輯

-Xmixed混合模式(預設是這個)

-Xint解釋模式,啟動很快,執行很慢

-Xcomp純編譯模式,執行很快,啟動慢

可以測試下,體驗下各種模式

 

public class TestwaytoRun {
    public static void main(String[] args) {
        for (int i = 0; i < 100000L; i++) {
            m();
        }

        long start = System.currentTimeMillis();
        for (int j = 0; j < 100000L; j++) {
            m();
        }
        long end = System.currentTimeMillis();
        System.out.println(end -start);
    }
    //耗費時間
    public static void m(){
        for (int i = 0; i < 100000L; i++) {
            long j = i%3;
        }
    }
}

 

 

 

相關文章