JVM體系結(jié)構(gòu)與工作方式

JVM體系結(jié)構(gòu)與工作方式

JAVA能夠跨越計算機硬件組成差異和操作系統(tǒng)的差異在不同的主機上運行间校,主要就是JVM屏蔽了各個主機之間硬件和軟件的差異花鹅,使得Java與平臺的耦合性交給JVM來解決魔熏。爪哇島的第二站就是從宏觀角度上介紹JVM的體系結(jié)構(gòu)和工作方式歇父。
目錄

JVM體系結(jié)構(gòu)

JVM是個什么東西?

JVM的全稱是Java Viutual Machine,也就是Java虛擬機,它運行在一個實際的計算機上并能仿真模擬出各種計算機的功能绒极。我們先來看一下一個真實的計算機如何才能具備計算的功能,從以計算為中心的計算機體系結(jié)構(gòu)來看蔬捷,他應(yīng)該具有以下幾部分:

  • 指令集:這個計算機所能識別的機器語言的命令集合垄提。
  • 計算單元:能夠識別并且控制指令執(zhí)行的功能模塊。
  • 尋址方式:地址的位數(shù)周拐,最小地址和最大地址范圍铡俐,以及地址的運行規(guī)則。
  • 寄存器定義:對操作數(shù)寄存器速妖、變址寄存器高蜂、控制寄存器等的定義、數(shù)量和使用方式罕容。
  • 存儲單元:能夠存儲操作數(shù)和保存操作結(jié)構(gòu)的單元备恤,如內(nèi)核級緩存、內(nèi)存和磁盤等等锦秒。
    上述五個部分中與代碼相關(guān)程度最大的還是指令集部分露泊,什么是指令集?他又有什么作用呢旅择?指令集是在CPU中用來計算和控制計算機系統(tǒng)的一套指令的集合惭笑,它是體現(xiàn)CPU性能的一個重要標(biāo)志。那指令集與匯編語言又有什么關(guān)系生真?指令集是可以直接被機器識別的機器碼沉噩,它必須以二進制格式存儲在計算機當(dāng)中,而匯編語言是能夠被人所識別的指令柱蟀,它在邏輯和順序上是與機器指令一一對應(yīng)的川蒙。
    每個運行的Java程序都是一個JVM實例,JVM和實體機一樣也有一套合適的指令集长已,這個指令集能夠被JVM解析執(zhí)行畜眨,這個指令集我們稱為JVM字節(jié)碼指令集昼牛。符合JVM規(guī)范的class文件字節(jié)碼都可以被JVM執(zhí)行。

Java代碼執(zhí)行流程圖

image

JVM體系機構(gòu)詳解

除了指令集之外康聂,JVM還需要以下四個組成部分:

  • 類加載器:在JVM啟動時或者在類運行時將需要的class加載到JVM中并解析成JVM統(tǒng)一使用的對象格式贰健。
  • 執(zhí)行引擎:執(zhí)行引擎的任務(wù)是負(fù)責(zé)執(zhí)行class文件中包含的字節(jié)碼指令,相當(dāng)于CPU恬汁。
  • 內(nèi)存區(qū):將內(nèi)存劃分為若干個區(qū)以模擬實際機器上的存儲伶椿、記錄和調(diào)度功能模塊。例如方法區(qū)蕊连,堆區(qū)悬垃,棧區(qū)和常量池等游昼。
  • 本地方法調(diào)用:調(diào)用C或C++實現(xiàn)的本地方法的代碼返回結(jié)果甘苍。

類加載器

類加載器作為JVM的對外接口,具有三個主要的功能:1.將class文件加載到JVM當(dāng)中烘豌;2.將Class字節(jié)碼重新解析成JVM統(tǒng)一要求的對象格式载庭;3.審查每個類應(yīng)該由誰來加載(是一種父優(yōu)先的等級加載機制)。

執(zhí)行引擎

執(zhí)行引擎是JVM的核心部分廊佩,執(zhí)行引擎的作用就是解析JVM字節(jié)碼指令囚聚,得到執(zhí)行結(jié)果。執(zhí)行引擎也就是執(zhí)行一條條代碼的一個流程标锄,每個Java線程都是一個執(zhí)行引擎的實例顽铸。執(zhí)行引擎一般有兩種執(zhí)行方式:
直接解釋執(zhí)行:解釋器會將代碼一句一句的進行解釋,沒解釋一句就運行一句料皇,在這個過程中不會產(chǎn)生機器碼文件谓松。
JIT(即時編譯器)執(zhí)行:先編譯再執(zhí)行,需要編譯器先將字節(jié)碼編譯成機器碼践剂,然后再進行執(zhí)行鬼譬,該過程會產(chǎn)生機器碼文件.
在實際JVM當(dāng)中會對代碼進行分類判斷,對于熱點代碼(多次調(diào)用的代碼和多次執(zhí)行的循環(huán)體)做編譯逊脯,非熱點代碼做解釋執(zhí)行优质。

Java內(nèi)存管理

JVM的執(zhí)行引擎在執(zhí)行一段程序時會存儲一些東西,比如操作碼需要的操作數(shù)军洼,操作碼的執(zhí)行結(jié)果等等巩螃。具體JVM的內(nèi)存區(qū)域管理和劃分會在下一篇文章進行解釋!

JVM工作方式

前面簡單分析了JVM的基本結(jié)構(gòu)匕争,下面再簡單分析一下JVM是如何執(zhí)行字節(jié)碼命令的避乏,也就是前面介紹的執(zhí)行引擎是如何工作的。

機器如何執(zhí)行代碼

我們知道機器語言一般都是和硬件平臺息息相關(guān)的汗捡,而高級語言一般都是屏蔽了所有的硬件平臺和軟件平臺(例如操作系統(tǒng))淑际。之所以能夠屏蔽就是有了編譯器畏纲,可以將高級語言轉(zhuǎn)化為CPU可以直接執(zhí)行的機器碼。通常一個程序從編寫到執(zhí)行會經(jīng)歷以下一些階段:
源代碼——>預(yù)處理器——>編譯器——>匯編程序——>目標(biāo)代碼——>鏈接器——>可執(zhí)行程序
除了源代碼和最后的可執(zhí)行程序春缕,中間的所有環(huán)節(jié)都是由現(xiàn)代意義上的編譯器統(tǒng)一完成的盗胀。

(值得注意的是,我們通常所說的編譯器都是將某種高級語言直接編譯成可執(zhí)行的目標(biāo)機器語言锄贼。但是實際上還有一些編譯器是將一種高級語言編譯成另外一種高級語言票灰,或者將低級語言編譯成高級語言(反編譯),或者將高級語言編譯成虛擬機目標(biāo)語言宅荤,如Java編譯器等屑迂。)

再回到如何讓機器(不論是虛擬機還是實體機)執(zhí)行代碼的主題,不論執(zhí)行什么代碼都可以進一步分解為二進制的位運算冯键,這些運算的核心目的就是確定需要運算的種類(操作碼)和運算的數(shù)據(jù)(操作數(shù))惹盼,以及從哪里獲取操作數(shù)(寄存器或者棧)和將運算結(jié)果存放到什么地方(寄存器或者棧)。因此基于兩種不同的存放方式(寄存器和棧)惫确,指令集會有基于寄存器的架構(gòu)實現(xiàn)和基于棧的架構(gòu)實現(xiàn)兩種方式手报。JVM選擇的是基于棧的架構(gòu)。

JVM為何選擇基于棧的架構(gòu)

JVM執(zhí)行字節(jié)碼指令是基于棧的架構(gòu)改化,也就是所有的操作數(shù)都必須先入棧掩蛤,然后再根據(jù)指令中的操作碼選擇從棧頂彈出若干個元素進行計算之后再壓入棧中。這就和一般的基于寄存器的操作有所不同陈肛,一個操作需要頻繁的入棧和出棧揍鸟,如果是基于寄存器(CPU的存儲器,讀取數(shù)據(jù)速度較快)的話不需要這么多的移動數(shù)據(jù)的操作句旱,那么為什么JVM仍然選擇基于棧的架構(gòu)呢阳藻?
主要的原因就是JVM要設(shè)計成平臺無關(guān)的,而平臺無關(guān)性就是要保證再沒有或者很少的寄存器的機器上也要同樣能正確執(zhí)行Java代碼前翎,而基于寄存器的架構(gòu)過于依賴于寄存器本身的硬件特性稚配,雖然基于寄存器可能會提高性能,但很大程度上犧牲了跨平臺的移植性港华,很難設(shè)計出一款通用的基于寄存器的指令道川,綜上所述,JVM最終選擇了基于棧的架構(gòu)立宜!

執(zhí)行引擎的架構(gòu)設(shè)計

了解了Java以棧為架構(gòu)的原因之后冒萄,再詳細(xì)看下JVM是如何設(shè)計Java的執(zhí)行部件的。
見下圖:

Java執(zhí)行部件


image

每當(dāng)創(chuàng)建了一個新的線程時橙数,JVM會為這個線程創(chuàng)建一個Java棧尊流,同時會為這個線程分配一個PC寄存器,并且此時這個PC寄存器會指向這個線程的第一行可執(zhí)行代碼(隨著線程的執(zhí)行灯帮,PC寄存器保持指向當(dāng)前正在執(zhí)行的代碼)崖技。每當(dāng)線程調(diào)用一個新方法時逻住,會在這個棧上創(chuàng)建一個新的棧幀數(shù)據(jù)結(jié)構(gòu),這個棧幀會保留這個方法的一些元信息迎献,如方法中定義的局部變量瞎访,正常方法返回以及異常處理機制等。JVM在調(diào)用某些指令時可能需要調(diào)用到常量池中的一些常量吁恍,Java對象和構(gòu)造函數(shù)等都存儲在所有線程共享的方法區(qū)和Java堆中扒秸。

執(zhí)行引擎的執(zhí)行過程

以一個方法的執(zhí)行過程解釋執(zhí)行引擎字節(jié)碼的指令流程:

public class Math{
    public static void main(String args[])
    {
        int a=1;
        int b=2;
        int c=(a+b)*10;
    }
}

其中main的字節(jié)碼指令如下:

偏移量    指令                      說明
0:      iconst_1                 常數(shù)1入棧
1:      istore_1                 將棧頂元素移入本地變量1存儲
2:      iconst_2                 常數(shù)2入棧
3:      istore_2                 將棧頂元素移入本地變量2存儲
4:      iload_1                  本地變量1入棧
5:      iload_2                  本地變量2入棧
6:      iadd                     彈出棧頂兩個元素相加之后將結(jié)果再入棧
7:      bipush 10                將10壓入棧 
8:      imul                     彈出棧頂兩個元素相乘之后再將結(jié)果入棧
9:      istore_3                 棧頂元素移入本地變量3存儲
10:     return                   返回

第十條指令執(zhí)行完,當(dāng)前的這個方法對應(yīng)的這些部件會被JVM回收冀瓦,局部變量區(qū)的所有值將全部釋放伴奥,PC寄存器會被銷毀,在Java棧中與這個方法對應(yīng)的棧幀將消失翼闽。

參考資料:
參考鏈接博客最下方
許令波——深入分析Java Web技術(shù)內(nèi)幕(第七章)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拾徙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子肄程,更是在濱河造成了極大的恐慌锣吼,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蓝厌,死亡現(xiàn)場離奇詭異,居然都是意外死亡古徒,警方通過查閱死者的電腦和手機拓提,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來隧膘,“玉大人代态,你說我怎么就攤上這事≌畛裕” “怎么了蹦疑?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長萨驶。 經(jīng)常有香客問我歉摧,道長,這世上最難降的妖魔是什么腔呜? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任叁温,我火速辦了婚禮,結(jié)果婚禮上核畴,老公的妹妹穿的比我還像新娘膝但。我一直安慰自己,他們只是感情好谤草,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布跟束。 她就那樣靜靜地躺著莺奸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冀宴。 梳的紋絲不亂的頭發(fā)上憾筏,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機與錄音花鹅,去河邊找鬼氧腰。 笑死,一個胖子當(dāng)著我的面吹牛刨肃,可吹牛的內(nèi)容都是我干的古拴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼真友,長吁一口氣:“原來是場噩夢啊……” “哼黄痪!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起盔然,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤桅打,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后愈案,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挺尾,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年站绪,在試婚紗的時候發(fā)現(xiàn)自己被綠了遭铺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡恢准,死狀恐怖魂挂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情馁筐,我是刑警寧澤涂召,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站敏沉,受9級特大地震影響果正,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赦抖,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一舱卡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧队萤,春花似錦轮锥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽新娜。三九已至,卻和暖如春既绩,著一層夾襖步出監(jiān)牢的瞬間概龄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工饲握, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留私杜,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓救欧,卻偏偏與公主長得像衰粹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子笆怠,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容