java虛擬機-虛擬機基本

什麼是java虛擬機

我一般是能記例子就不記概念,不過概念還是要貼出來的

概念

Java虛擬機(Java Virtual Machine 簡稱JVM)是運行所有Java程序的抽象計算機,是Java語言的運行環境,它是Java 最具吸引力的特性之一。(copy的百度)

通俗易懂的理解

public class AA{
	public static void main(String[] args) throws InterruptedException {
        Thread.sleep(10000000);
    }
}

首先寫一段代碼,然後cmd javac一下 然後用java AA啓動,win10的環境下可以看到
在這裏插入圖片描述
看到了我們熟悉的東西,其實這就是虛擬機的一個實例

jvm的生命週期

根據上面的例子應該很明顯就能知道生命週期的開始就是main開始運行的時候,但是並不是說main結束就是jvm生命週期的結束 做個試驗

public static void main(String[] args) {
        new Thread(()-> {
            System.out.println("sleep");
            try {
                Thread.sleep(1000000000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } ).start();
        System.out.println("main over");
    }

還是上面的代碼把main方法改下 重新編譯 運行
在這裏插入圖片描述
main已經結束了 可是虛擬機還在

這是由於java的虛擬機種有兩種線程,一種叫叫守護線程,一種叫非守護線程,main函數就是個非守護線程,虛擬機的垃圾回收線程就是守護線程。

java的虛擬機中,只要有任何非守護線程還沒有結束,java虛擬機的實例都不會退出,所以即使main函數這個非守護線程退出,但是由於在main函數中啓動的匿名線程也是非守護線程,它還沒有結束,所以jvm沒辦法退出。

總結: java虛擬機的生命週期,當一個java應用main函數啓動時虛擬機也同時被啓動,而只有當在虛擬機實例中的所有非守護進程都結束時,java虛擬機實例才結束生命。

java虛擬機的體系結構

在這裏插入圖片描述

在 Java虛擬機規範中,一個虛擬機實例的行爲是分別按照子系統、內存區、數據類型和指令來描述的,這些組成部分一起展示了抽象的虛擬機的內部體系結構。

類裝載器子系統

類裝載器子系統負責查找並裝載類型信息。其實Java虛擬機有兩種類裝載器:系統裝載器和用戶自定義裝載器。前者是Java虛擬機實現的一部分,後者則是Java程序的一部分。

  • 啓動類裝載器(bootstrap class loader):它用來加載 Java
    的核心庫,是用原生代碼來實現的,並不繼承自java.lang.ClassLoader。
  • 擴展類裝載器(extensions class loader):它用來加載 Java 的擴展庫。Java
    虛擬機的實現會提供一個擴展庫目錄。該類加載器在此目錄裏面查找並加載 Java 類。
  • 應用程序類裝載器(application class loader):它根據 Java 應用的類路徑(CLASSPATH)來加載 Java
    類。一般來說,Java 應用的類都是由它來完成加載的。可以通過
    ClassLoader.getSystemClassLoader()來獲取它。

除了系統提供的類裝載器以外,開發人員可以通過繼承 java.lang.ClassLoader類的方式實現自己的類裝載器,以滿足一些特殊的需求。

類裝載器子系統涉及Java虛擬機的其它幾個組成部分以及來自java.lang庫的類。ClassLoader定義的方法爲程序提供了訪問類裝載器機制的接口。此外,對於每一個被裝載的類型,Java虛擬機都會爲它創建一個java.lang.Class類的實例來代表該類型。和其它對象一樣,用戶自定義的類裝載器以及Class類的實例放在內存中的堆區,而裝載的類型信息則位於方法區。

類裝載器子系統除了要定位和導入二進制class文件外,還必須負責驗證被導入類的正確性,爲類變量分配並初始化內存,以及解析符號引用。這些動作還需要按照以下順序進行:

  1. 裝載(查找並裝載類型的二進制數據)

  2. 連接(執行驗證:確保被導入類型的正確性;準備:爲類變量分配內存,並將其初始化爲默認值;解析:把類型中的符號引用轉換爲直接引用)

  3. 初始化(類變量初始化爲正確初始值)

運行時數據區

這個放下一篇,連接:點我看內容

執行引擎

在Java虛擬機規範中,執行引擎的行爲使用指令集定義。實現執行引擎的設計者將決定如何執行字節碼,實現可以採取解釋、即時編譯或直接使用芯片上的指令執行,還可以是它們的混合。

執行引擎可以理解成一個抽象的規範、一個具體的實現或一個正在運行的實例。抽象規範使用指令集規定了執行引擎的行爲。具體實現可能使用多種不同的技術–包括軟件方面、硬件方面或樹種技術的結合。作爲運行時實例的執行引擎就是一個線程。

運行中Java程序的每一個線程都是一個獨立的虛擬機執行引擎的實例。從線程生命週期的開始到結束,它要麼在執行字節碼,要麼執行本地方法。

指令集

方法的字節碼流由Java虛擬機的指令序列構成。每一條指令包含一個單字節的操作碼,後面跟隨0個或多個操作數。操作碼錶示需要執行的操作;操作數向Java虛擬機提供執行操作碼需要的額外信息。當虛擬機執行一條指令時,可能使用當前常量池中的項、當前幀的局部變量中的值或者位於當前幀操作數棧頂端的值。

抽象的執行引擎每次執行一條字節碼指令。Java虛擬機中運行的程序的每個線程(執行引擎實例)都執行這個操作。執行引擎取得操作碼,如果操作碼有操作數,就取得它的操作數。它執行操作碼和跟隨的操作數規定的動作,然後再取得下一個操作碼。這個執行字節碼的過程在線程完成前將一直持續,通過從它的初始方法返回,或者沒有捕獲拋出的異常都可以標誌着線程的完成。

本地方法接口

Java本地接口,也叫JNI(Java Native Interface),是爲可移植性準備的。本地方法接口允許本地方法完成以下工作:

  • 傳遞或返回數據
  • 操作實例變量
  • 操作類變量或調用類方法
  • 操作數組
  • 對堆的對象加鎖
  • 裝載新的類
  • 拋出異常
  • 捕獲本地方法調用Java方法拋出的異常
  • 捕獲虛擬機拋出的異步異常
  • 指示垃圾收集器某個對象不再需要
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章