詳細理解Java虛擬機器的執行過程
基本概述:
Java虛擬機器簡稱JVM,是JRE中的一部分,也是Java程式執行的最關鍵的部分。完整的Java執行流程大致包括編譯.java檔案形成.class檔案,然後根據.class檔案的內容進行一系列的步驟使整個程式執行起來。其中將.java檔案編譯為.class檔案由Java編譯器完成,而由.class檔案進而完成整個執行過程則主要是由JVM來完成的。由於所有的編譯連結過程都由JRE來完成,所以Java具有良好的平臺可移植性,不依賴具體的作業系統。
具體結構及功能:
1、Class Loader:
該子系統主要負責以下三種工作。
一、讀取(Loading):Class Loader會首先讀取由Java編譯器傳入的.class檔案,然後生成相對應的二進位制資料並將其存入方法區,這其中生成的資料主要包括類名、緊鄰的父類、各種修飾符、變數和方法的資訊。在這之後,JVM會自動給這個類建立一個型別為Class的物件並存入堆中,這個物件可以被程式設計師呼叫,從而得到這個類中的相關資訊(也就是上面所講的存入方法區的那些資訊)。需要注意的是,一個類只會具有一個Class物件,也就是說,就算有無窮個該類的不同物件,在堆中也只會有一個對應的Class物件。
二、連結(Linking):在讀取之後,Class Loader會對.class檔案進行正確性驗證,看看該類是否被正確定義,同時是否被正確編譯。如果驗證成功,那麼JVM就會為類中的變數分配記憶體,並且初始化記憶體為預設值。
三、初始化(Initialization):在這一階段,所有的靜態變數將被正確賦值,賦值的順序是按照程式碼順序從前往後,從父類到子類。
而對於Class Loader來說,其實也大致分為三類。第一類是Bootstrap Class Loader,我們可以理解為最基礎的Class Loader,因為它只會處理那些已經被完全信任的class,也就是Java的核心類;第二類是Extension Class Loader,它會處理那些被放置在指定的擴充套件類資料夾中的類;第三類是Application Class Loader,它處理的是外界定義的類。至於其中的具體不同呢,在此就不展開敘述了。
2、JVM Memory:
JVM的記憶體區是其存放具體資料和物件的主要區域,總共由以下五部分組成。
一、方法區(Method Area):方法區中主要存取的是Class級別的資料,包括類名,父類名,方法名,變數名和靜態變數等等。每一個JVM只有一塊方法區,所以是一個可以被所有類和程序共享的區域。
二、堆(Heap Area):堆中存放著所有物件的資訊。每一個JVM也只有一個堆,意味著堆也是被共享的。
三、棧(Stack Area):JVM會為每一個執行緒開闢一個棧區,而每一個棧區中又會分成許多的塊(Block),每一個塊都代表一個方法呼叫,方法中的所有本地變數都會存放在棧中相對應的塊中。一旦該執行緒終止,那麼這個棧就會被JVM銷燬。所以棧區是不共享的。
四、PC計數器(PC Register):記錄每一個執行緒當前執行到的程式碼地址。顯然,每一個執行緒都會有一個對應的PC計數器,所以也是不共享的。
五、本地方法區(Native Method Area):每一個執行緒都會有一個本地方法區,其主要存放本地方法的相關資訊。
3、Execution Engine:
執行引擎負責真正地執行.class檔案,它會一行一行地讀取.class中的二進位制資訊,然後利用JVM Memory中的資料一條一條地執行。垃圾回收器也是在這個引擎中,它可以自動檢測不再可能被引用的已分配記憶體並將其回收。
JVM的大致執行過程到這裡就告一段落了。當然,還有許許多多的細節在這裡沒有列出,如果有需要,查閱官方文件是最好的辦法。