1. 程式人生 > >第七章 JVM體系結構與工作方式

第七章 JVM體系結構與工作方式

硬件 java內存管理 彈出 操作符 clas 基本 記錄器 pan 操作

JVM能跨計算機體系結構來執行Java字節碼,主要是由於JVM屏蔽了與各個計算機平臺的軟件和硬件之間的差異。

7.1 JVM體系結構

  7.1.1 何謂JVM

    模擬一個計算機來達到一個計算機所具有的計算功能。

    以計算為中心來看計算機的體系結構可以分為如下幾個部分。

  •  指令集 計算機能識別的機器語言的命令集合。
  •  計算單元 能夠識別並且控制指令執行的功能模塊。
  •  尋址方式 地址的位數,最小地址和最大地址範圍,以及地址的運行規則。
  •  寄存器定義 包括操作數寄存器,變址寄存器,控制寄存器等的定義,數量和使用方式。
  •  存儲單元 能夠存儲操作數和保存操作結構的單元,如內核級緩存,內存和磁盤等。

每一個匯編語句可以翻譯成一條機器指令。

CPU架構是否影響指令集?因為在匯編語言中都是對寄存器和段的直接操作的命令,所以不同的芯片架構設計一定會對應不同的機器指令集合。

JVM和實體機有何區別?

  • 一個抽象規範:這個規範約束了JVM到底是什麽?有哪些組成部分
  • 一個具體實現:不同的廠商按照抽象的規範實現
  • 一個運行中的實例:當用其運行一個JAVA程序時,它就是一個運行中的實例,每一個運行中的實例,都是一個JVM實例。

  7.1.2 JVM體系結構詳解

  • 類加載器:JVM啟動時或者在類運行時將需要的class加載到JVM種。
  • 執行引擎:執行class文件中包含的字節碼指令,相當於實際機器上的CPU。
  • 內存區:將內存分成若幹個區以模擬實際機器上的存儲、記錄和調度功能模塊,如實際機器上的各種功能的寄存器或PC指針的記錄器等。
  • 本地方法調用:調用C或C++實現的本地方法的代碼返回結果。技術分享

1 類加載器:每個被JVM轉載的類都有一個對應的java.lang.Class類的實例來表示該類型,該實例可以唯一表示被JVM裝載的class類,這個實例在JAVA堆中,

   2 執行引擎:JVM核心,作用是解析JVM字節碼指令,得到執行結果。JAVA虛擬機規範定義了執行引擎遇到每條字節碼指令時應該處理什麽,得到什麽結果。但是

         沒有規定用何種方式。所以各JVM廠商自己決定。

          執行引擎也就是執行一條條代碼的一個流程,代碼包含在方法體內,所以執行引擎本質上就是執行一個個方法所串起來的流程。JVM同時運行多個線程,

          每個線程就是一個執行引擎的的實例。這些執行引擎有的執行用戶程序,有的執行JVM內部程序(垃圾回收)

   3 JAVA內存管理:方法區,Java堆,JAVA棧,PC寄存器和本地方法區。其中方法區和JAVA堆是所有線程共享的,可以被所有執行引擎實例共享,每個新的執行引擎實例被

           創建的時候會創建JAVA棧和一個PC寄存器。如果當前正在執行一個JAVA方法,那麽當前這個JAVA棧中保存的是該線程中方法調用的狀態,包括方法參數,局部

           變量,方法返回值以及運算的中間結果。PC指向下一條指令。

7.2 JVM工作機制

  JVM如何執行字節碼命令的,也就是執行引擎是如何工作的 。

  不管是何種指令集都是只有幾種基本的元素:加 減 乘 求余 求模等。這些又可以進一步分解成二進制位運算:與 或 異或等。這些運算都是通過指令來完成,而指令的核心目的就是確定需要運算的種類(操作符)和運算需要的數據(操作數),以及從哪裏(寄存器或棧)獲取操作數,將操作結果放在什麽地方(寄存器或棧)。這種不同的操作方式又將指令劃分成:一地址指令,二地址指令,三地址指令和零地址指令。相應的指令集會有對應的架構實現,如基於寄存器的架構實現或者基於棧的架構實現,這裏的基於什麽實現是指在一個指令中的操作數是如何存取的。

  7.2.1 機器如何執行代碼

  JVM執行字節碼指令是基於棧的結構, 也就是所有的操作數必須先入棧,然後根據指令中的操作碼選擇從棧頂彈出若幹個元素進行計算後再將結果入棧。

  在JVM中操作數可以存放在每一個棧幀的本地變量集中,每個方法在調用時,給分配本地變量集,這個本地變量集在編譯的時候就確定了,所以操作數入棧就是常量入棧或者從本地變量集中取變量入棧。這和基於寄存器的操作不同:操作數要頻繁的入棧和出棧,比如進行加法,如果兩個操作數都在本地變量集中,那麽一個加法操作需要5次棧操作;如果是基於寄存器的話,只需要將兩個操作數放入寄存器進行加法運算後再將結果放入寄存器就可以。不需要這樣多的數據移動操作。那麽JVM為什麽基於棧來設計呢?

  7.2.2 JVM為何選擇基於棧的結構

 理由:一是JVM要設計成平臺無關的,在有很少或沒有寄存器的機器上同樣可以正確的執行JAVA代碼,基於寄存器的架構很難做到通用。

     二是為了指令的緊湊性,

  7.2.3 執行引擎的結構設計

  每當創建一個新的線程時,JVM會為這個線程創建一個JAVA棧,同時分配一個PC寄存器,並且這個PC寄存器會指向這個線程第一行可執行代碼。每當調用一個新方法時,會創建一個新的棧幀結構,棧幀會保存這個方法的一些元信息,如在這個方法中定義的局部變量,一些用來支撐常量池的解析,正常方法返回和異常處理。

  技術分享

常量區: 類型信息 類型的常量池( constant pool)
域(Field)信息
方法(Method)信息
除了常量外的所有靜態(static)變量

  7.2.4 執行引擎的執行過程

  7.2.5 JVM方法調用棧

  JVM的方法調用分為兩種:一種是JAVA方法調用;另一種是本地方法調用。

第七章 JVM體系結構與工作方式