1. 程式人生 > >Java虛擬機器體系結構概述

Java虛擬機器體系結構概述

Java虛擬機器之所以稱為“虛擬”,就是因為它僅僅是由一個規範來定義的抽象計算機。要執行某個Java程式,首先需要一個符合該規範的具體實現。下面主要討論這個規範本身。

Java虛擬機器是什麼
   要理解Java虛擬機器,你必須意識到,當你說“Java虛擬機器”時,可能指的是如下三種不同的東西:

  • 抽象規範 
  • 一個具體的實現 
  • 一個執行中的虛擬機器例項

Java虛擬機器抽象規範僅僅是個概念。該規範的具體實現,可能來自多個提供商,並存在多個平臺上。它或者完全用軟體實現,或者以硬體和軟體相結合的方式來實現。當執行一個Java程式的同時,也就在運行了一個Java虛擬機器例項。

Java虛擬機器的生命週期
   一個執行時的Java虛擬機器例項的天職就是:負責執行一個Java程式。當啟動一個Java程式時,一個虛擬機器例項也就誕生了。當該程式關閉推出,這個虛擬機器例項也就隨之消亡。每個Java程式都執行在於自己的Java虛擬機器例項中。Java虛擬機器例項通過呼叫某個初始類的main()方法來執行一個Java程式。而這個main()方法必須是public,static,返回值為void。main()方法作為該程式初始執行緒的起點,任何其他的執行緒都是由這個初始執行緒啟動的。
   Java虛擬機器內部有兩種執行緒:守護執行緒和非守護執行緒。守護執行緒通常由虛擬機器自己使用的,比如執行垃圾收集任務的執行緒。但是,Java程式也可以把它的建立的任何執行緒標記為守護執行緒。而Java程式中的初始執行緒,就是開始於main()的那個,是非守護執行緒。只要有非守護執行緒在執行,那麼這個Java程式也在繼續執行,只有該程式中所有的非守護執行緒都終止時,虛擬機器例項將自動退出。

Java虛擬機器的體系結構
  Java虛擬機器的結構分為:類裝載子系統,執行時資料區,執行引擎,本地方法介面。其中執行時資料區又分為:方法區,堆,Java棧,PC暫存器,本地方法棧。

類裝載子系統
  Java虛擬機器中,負責查詢並裝載型別的那部分稱為類裝載子系統。
  Java虛擬機器有兩種類裝載器:啟動類裝載器和使用者自定義類裝載器。啟動類裝載器是Java虛擬機器實現的一部分。使用者自定義類裝載器是Java程式的一部分。
  類裝載器的動作:

  1. 裝載---查詢並裝載型別的二進位制資料
  2. 連線---執行驗證,準備,以及解析(可選)
    驗證:確保被匯入型別的正確性
    準備:為類變數分配記憶體,並將其初始化為預設值
    把型別中的符號引用換為直接引用
  3. 初始化---把類變數初始化為正確的初始值

方法區
  在Java虛擬機器中,被裝載型別的資訊儲存在一個邏輯上被稱為方法區的記憶體中。當虛擬機器裝載某個型別時,它使用類裝載器定位相應的class檔案,然後讀入這個class檔案,然後將它傳輸到虛擬機器中,緊接著虛擬機器提取其中的型別資訊,並將這些資訊儲存到方法區。該型別中的類(靜態)變數同樣也是儲存在方法區中。方法區的大小不必固定,可以根據需要動態調整。方法區也可以被垃圾收集,因為虛擬機器允許通過使用者定義的類裝載器來動態擴充套件Java程式,因此,一些類也會成為“不再引用”的類。 
  對於每個裝載的型別,虛擬機器都會在方法區中儲存以下型別資訊:

  • 這個型別的全限定名。
  • 這個型別的直接超類的全限定名(除非是java.lang.Object,無超類)
  • 這個型別是類型別還是介面型別。
  • 這個型別的訪問修飾符(public,abstract ...)
  • 任何直接超介面的全限定名的有序列表

除了上面列出的基本型別資訊外,虛擬機器還為每個被裝載的型別儲存以下資訊

  • 該型別的常量池
  • 欄位資訊
  • 方法資訊
  • 除了常量以外所有類(靜態)變數
  • 一個到類ClassLoader的引用
  • 一個到Class類的引用