天天看點

「JVM系列」一步步解析java執行内幕

對于任何一門語言,要想達到精通的水準,研究它的執行原理(或者叫底層機制)不失為一種良好的方式。在本篇文章中,将重點研究java源代碼的執行原理,即從程

序員編寫JAVA源代碼,到最終形成産品,在整個過程中,都經曆了什麼?每一步又是怎麼執行的?執行原理又是什麼?…

當然,本篇文章的粒度可能稍微側重于宏觀方面,更細粒度的技術分析,需要在接下來的該系列文章中與大家分享…

「JVM系列」一步步解析java執行内幕

一 編寫java源程式

java源檔案:指存儲java源碼的檔案;

目前比較主流的JAVA IDE?

(1)Intellij IDEA(首推薦)

(2)Eclipse

先來看看如下代碼:

//MyTest被public修飾,故存儲該java源碼的檔案名為MyTest

public class MyTest {

public static void main(String[] args){

System.out.println(“Test Java execute process.”);

}

}

//由于MyTest被public修飾了,故Class A不能用public修飾

class A{}

//由于MyTest被public修飾了,故Class B不能用public修飾

class B{}

(1)java源檔案名就是該源檔案中public類的名稱

「JVM系列」一步步解析java執行内幕

(2)一個java源檔案可以包含多個類,但隻允許一個類為public

二 編譯java源代碼

當java源程式編碼結束後,就需要編譯器編譯,安裝好jdk後,我們打開jdk目錄,有兩個.exe檔案,
           

即javac.exe(編譯源代碼,即.java檔案)和java.exe(執行位元組碼,即.class檔案)

「JVM系列」一步步解析java執行内幕

「JVM系列」一步步解析java執行内幕

Java技術進階 2019-07-03 17:24

對于任何一門語言,要想達到精通的水準,研究它的執行原理(或者叫底層機制)不失為一種良好的方式。在本篇文章中,将重點研究java源代碼的執行原理,即從程

序員編寫JAVA源代碼,到最終形成産品,在整個過程中,都經曆了什麼?每一步又是怎麼執行的?執行原理又是什麼?…

當然,本篇文章的粒度可能稍微側重于宏觀方面,更細粒度的技術分析,需要在接下來的該系列文章中與大家分享…

一 編寫java源程式

java源檔案:指存儲java源碼的檔案;

目前比較主流的JAVA IDE?

(1)Intellij IDEA(首推薦)

(2)Eclipse

先來看看如下代碼:

//MyTest被public修飾,故存儲該java源碼的檔案名為MyTest

public class MyTest {

public static void main(String[] args){

System.out.println(“Test Java execute process.”);

}

}

//由于MyTest被public修飾了,故Class A不能用public修飾

class A{}

//由于MyTest被public修飾了,故Class B不能用public修飾

class B{}

(1)java源檔案名就是該源檔案中public類的名稱

(2)一個java源檔案可以包含多個類,但隻允許一個類為public

二 編譯java源代碼

當java源程式編碼結束後,就需要編譯器編譯,安裝好jdk後,我們打開jdk目錄,有兩個.exe檔案,

即javac.exe(編譯源代碼,即.java檔案)和java.exe(執行位元組碼,即.class檔案)

1.切換到MyTest.java檔案夾

「JVM系列」一步步解析java執行内幕

2.javac.exe編譯MyTest.java

「JVM系列」一步步解析java執行内幕

編譯後,發現e:\Blogs 目錄多了以class為字尾的檔案:A.class,B.class和MyTest.class

「JVM系列」一步步解析java執行内幕

Tip:當javac.exe編譯java源代碼時,java源代碼有幾個類,就會編譯成一個對應的位元組碼檔案(.class檔案),

其中,位元組碼檔案的檔案名就是每個類的類名。需要注意的是,類即使不在源檔案中定義,但被源檔案引用,

編譯後,也會程式設計相應的位元組碼檔案,如類A引用類C,但類C不定義在類A的源檔案中,編譯後,類C也被編

譯成對應的位元組碼檔案C.class

三 執行java源檔案

執行java源檔案,用java.exe執行即可

「JVM系列」一步步解析java執行内幕

到現在,java源程式基本執行結果,并正确列印我們期望的結果,那麼,如上的步驟,我們可以總結如下:

「JVM系列」一步步解析java執行内幕

如上總結,已經抽象化了在JVM中的執行,接下來,我們将分析,位元組碼檔案(.calss檔案)如何在虛拟機中一步一執行的。

四 JVM如何執行位元組碼檔案

(一) 裝載位元組碼檔案

當.java源碼被javac.exe編譯器編譯成.class位元組碼檔案後,接下來的工作就交給JVM處理,JVM首先通過類加載器(ClassLoader)

将class檔案和相關Java API加載裝入JVM,以供JVM後續處理。

在該階段中,涉及到如下一些基本概念和知識。

1.JDK,JRE和JVM關系

(1)JDK(Java Development Kit),Java開發工具包,主要用于開發,在JDK7前,JDK包括JRE

(2)JRE(Java Runtime Environment),Java程式運作的核心環境,包括JVM和一些核心庫

(3)JVM(Java Virtual Machine),VM是一種用于計算裝置的規範,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模拟

各種計算機功能來實作的,是JRE核心子產品。

2.JVM

JVM是一種用于計算裝置的規範,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模拟各種計算機功能來實作的。Java虛拟機

虛拟機的主要任務是裝載class檔案并執行其中的位元組碼,不同的Java虛拟機中,執行引擎可能由不同的實作,大緻有如下幾種引擎:

一次性解釋位元組碼引擎

即時編譯引擎

自适應優化器

關于虛拟機的實作方式,采用軟體方式、硬體方式和軟體硬體結合方式,這個要根據具體廠商而定。

3.什麼是ClassLoader

虛拟機的主要任務是裝載class檔案并執行其中的位元組碼,而class檔案是由虛拟機的類加載器(ClassLoader)完成的,在一個Java虛拟機,

有可能存在多個類加載器。

任何java運用程式,可能會使用兩種類加載器,即啟動類加載器(bootstrap)和使用者自定義類加載器。

啟動類加載器是Java虛拟機唯一實作的一部分,它又可分為原始類裝載器,系統類裝載器或預設類裝載器,它的主要作用是從作業系統的

磁盤裝載相應的類,如Java API類等。

使用者自定義裝載類,按照使用者自定義的方式來裝載類。

「JVM系列」一步步解析java執行内幕

(二)将位元組碼檔案存儲在JVM記憶體區

當JAVA虛拟機運作一個程式時,它需要記憶體來存儲許多東西,如位元組碼,從已裝載的class檔案中得到的其他資訊,程式建立的對象,傳遞給

方法的參數,傳回值,局部變量以及運算的中間結果等,這些相關資訊被組織到“運作時資料區”。

根據廠商的不同,在Java虛拟機中,運作時資料區也有所不同,有些運作時資料區由線程共享,有些隻能由某個特定線程共享。運作時資料區

大緻可分幾個區:方法區,堆區,棧區,PC寄存器區和本地方法棧區。

在該階段中,涉及到如下基本概念和知識。

1.方法區

方法區用來存儲解析被加載的class檔案的相關資訊。當虛拟裝載一個class檔案後,它會從這個class檔案包含的二進制資料中解析類型資訊,然後将

該相關資訊存儲到方法區中。

2.堆

堆是用來存儲相關引用類型的,如new對象。當程式運作時,虛拟機會把所有該程式在運作時建立的對象都放到堆中。

3.PC寄存器

PC寄存器主要用來存儲線程。當新建立一個線程時,該線程都将得到一個自己的PC寄存器(程式計數器)以及一個java棧。

Java虛拟機沒有寄存器,其指令集使用Java棧來存儲中間資料。

4.棧區

棧區主要用來存儲值類型的,如基本資料類型,需要注意的時,String為引用類型,是存在堆中的。Java棧是由許多棧

幀組成的,一個棧幀包含一個Java方法調用的狀态,當線程調用一個方法時,虛拟機壓入一個新的棧幀到該線程的Java棧中

,當該方法傳回時,這個棧幀從Java棧中彈出。

「JVM系列」一步步解析java執行内幕

(三)執行引擎與運作時資料區互動

運作時資料區為執行引擎提供了執行環境和相關資料,執行引擎通過與運作時資料區互動,進而擷取

執行時需要的相關資訊,存儲執行的中間結果等

「JVM系列」一步步解析java執行内幕

(四)執行引擎與本地方法接口

當要執行本地方法時,執行引擎将調用本地方法接口來擷取相關OS本地方法,需要注意的是,本地方法與作業系統強耦合的。

「JVM系列」一步步解析java執行内幕

(五)JVM在具體作業系統上執行

JVM通過調用本地接口來擷取本地方法,進而實作在具體的平台上執行,如在Linux系統上執行,在Window系統上

執行和在Unix系統上執行。

「JVM系列」一步步解析java執行内幕

五 參考文獻

【01】深入Java虛拟機(原書第2版)(美)Bill Venners 著

【02】Core Java Volume I - Fundamententals(10th Edition) (美) Cay S.Horstmann

【03】Core Java Volume I - Advanced Features(10th Edition) (美) Cay S.Horstmann

寫在最後:

碼字不易看到最後了,那就點個關注呗,隻收藏不點關注的都是在耍流氓!

關注并私信我“架構”,免費送一些Java架構資料,先到先得!