新聞中心
本文向大家簡單介紹一下Java虛擬機(jī)體系結(jié)構(gòu),Java虛擬機(jī)由五個部分組成,這五部分是Java虛擬機(jī)的邏輯成份,不依賴任何實(shí)現(xiàn)技術(shù)或組織方式,但它們的功能必須在真實(shí)機(jī)器上以某種方式實(shí)現(xiàn)。

Java虛擬機(jī)體系結(jié)構(gòu)
Java虛擬機(jī)由五個部分組成:一組指令集、一組寄存器、一個棧、一個無用單元收集堆(Garbage-collected-heap)、一個方法區(qū)域。這五部分是Java虛擬機(jī)的邏輯成份,不依賴任何實(shí)現(xiàn)技術(shù)或組織方式,但它們的功能必須在真實(shí)機(jī)器上以某種方式實(shí)現(xiàn)。
1.Java指令集
Java虛擬機(jī)支持大約248個字節(jié)碼。每個字節(jié)碼執(zhí)行一種基本的CPU運(yùn)算,例如,把一個整數(shù)加到寄存器,子程序轉(zhuǎn)移等。Java指令集相當(dāng)于Java程序的匯編語言?! ?/p>
Java指令集中的指令包含一個單字節(jié)的操作符,用于指定要執(zhí)行的操作,還有0個或多個操作數(shù),提供操作所需的參數(shù)或數(shù)據(jù)。許多指令沒有操作數(shù),僅由一個單字節(jié)的操作符構(gòu)成?! ?/p>
Java虛擬機(jī)的內(nèi)層循環(huán)的執(zhí)行過程如下:
- do{
- 取一個操作符字節(jié);
- 根據(jù)操作符的值執(zhí)行一個動作;
- }while(程序未結(jié)束)
由于指令系統(tǒng)的簡單性,使得Java虛擬機(jī)執(zhí)行的過程十分簡單,從而有利于提高執(zhí)行的效率。指令中操作數(shù)的數(shù)量和大小是由操作符決定的。如果操作數(shù)比一個字節(jié)大,那么它存儲的順序是高位字節(jié)優(yōu)先。例如,一個16位的參數(shù)存放時占用兩個字節(jié),其值為:
***個字節(jié)*256+第二個字節(jié)字節(jié)碼指令流一般只是字節(jié)對齊的。指令tabltch和lookup是例外,在這兩條指令內(nèi)部要求強(qiáng)制的4字節(jié)邊界對齊。
2.寄存器
Java虛擬機(jī)的寄存器用于保存機(jī)器的運(yùn)行狀態(tài),與微處理器中的某些專用寄存器類似?! ?/p>
Java虛擬機(jī)的寄存器有四種:
◆pc:Java程序計(jì)數(shù)器?! ?/p>
◆optop:指向操作數(shù)棧頂端的指針?! ?/p>
◆frame:指向當(dāng)前執(zhí)行方法的執(zhí)行環(huán)境的指針?! ?/p>
◆vars:指向當(dāng)前執(zhí)行方法的局部變量區(qū)***個變量的指針。#p#
3.棧
Java虛擬機(jī)的棧有三個區(qū)域:局部變量區(qū)、運(yùn)行環(huán)境區(qū)、操作數(shù)區(qū)?! ?/p>
(1)局部變量區(qū)每個Java方法使用一個固定大小的局部變量集。
它們按照與vars寄存器的字偏移量來尋址。局部變量都是32位的。長整數(shù)和雙精度浮點(diǎn)數(shù)占據(jù)了兩個局部變量的空間,卻按照***個局部變量的索引來尋址。(例如,一個具有索引n的局部變量,如果是一個雙精度浮點(diǎn)數(shù),那么它實(shí)際占據(jù)了索引n和n+1所代表的存儲空間。)Java虛擬機(jī)規(guī)范并不要求在局部變量中的64位的值是64位對齊的。Java虛擬機(jī)提供了把局部變量中的值裝載到操作數(shù)棧的指令,也提供了把操作數(shù)棧中的值寫入局部變量的指令。
(2)運(yùn)行環(huán)境區(qū)在運(yùn)行環(huán)境中包含的信息用于動態(tài)鏈接,正常的方法返回以及異常傳播?! ?/p>
◆動態(tài)鏈接
運(yùn)行環(huán)境包括對指向當(dāng)前類和當(dāng)前方法的解釋器符號表的指針,用于支持方法代碼的動態(tài)鏈接。方法的class文件代碼在引用要調(diào)用的方法和要訪問的變量時使用符號。動態(tài)鏈接把符號形式的方法調(diào)用翻譯成實(shí)際方法調(diào)用,裝載必要的類以解釋還沒有定義的符號,并把變量訪問翻譯成與這些變量運(yùn)行時的存儲結(jié)構(gòu)相應(yīng)的偏移地址。動態(tài)鏈接方法和變量使得方法中使用的其它類的變化不會影響到本程序的代碼?! ?/p>
◆正常的方法返回
如果當(dāng)前方法正常地結(jié)束了,在執(zhí)行了一條具有正確類型的返回指令時,調(diào)用的方法會得到一個返回值。執(zhí)行環(huán)境在正常返回的情況下用于恢復(fù)調(diào)用者的寄存器,并把調(diào)用者的程序計(jì)數(shù)器增加一個恰當(dāng)?shù)臄?shù)值,以跳過已執(zhí)行過的方法調(diào)用指令,然后在調(diào)用者的執(zhí)行環(huán)境中繼續(xù)執(zhí)行下去?! ?/p>
◆異常和錯誤傳播
異常情況在Java中被稱作Error(錯誤)或Exception(異常),是Throwable類的子類,在程序中的原因是:
①動態(tài)鏈接錯,如無法找到所需的class文件。
②運(yùn)行時錯,如對一個空指針的引用
◆程序使用了throw語句。
當(dāng)異常發(fā)生時,Java虛擬機(jī)采取如下措施:
◆檢查與當(dāng)前方法相聯(lián)系的catch子句表。每個catch子句包含其有效指令范圍,能夠處理的異常類型,以及處理異常的代碼塊地址。
◆與異常相匹配的catch子句應(yīng)該符合下面的條件:造成異常的指令在其指令范圍之內(nèi),發(fā)生的異常類型是其能處理的異常類型的子類型。如果找到了匹配的catch子句,那么系統(tǒng)轉(zhuǎn)移到指定的異常處理塊處執(zhí)行;如果沒有找到異常處理塊,重復(fù)尋找匹配的catch子句的過程,直到當(dāng)前方法的所有嵌套的catch子句都被檢查過。
◆由于Java虛擬機(jī)從***個匹配的catch子句處繼續(xù)執(zhí)行,所以catch子句表中的順序是很重要的。因?yàn)镴ava代碼是結(jié)構(gòu)化的,因此總可以把某個方法的所有的異常處理器都按序排列到一個表中,對任意可能的程序計(jì)數(shù)器的值,都可以用線性的順序找到合適的異常處理塊,以處理在該程序計(jì)數(shù)器值下發(fā)生的異常情況。
◆如果找不到匹配的catch子句,那么當(dāng)前方法得到一個"未截獲異常"的結(jié)果并返回到當(dāng)前方法的調(diào)用者,好像異常剛剛在其調(diào)用者中發(fā)生一樣。如果在調(diào)用者中仍然沒有找到相應(yīng)的異常處理塊,那么這種錯誤傳播將被繼續(xù)下去。如果錯誤被傳播到最頂層,那么系統(tǒng)將調(diào)用一個缺省的異常處理塊?! ?/p>
(3)操作數(shù)棧區(qū)機(jī)器指令只從操作數(shù)棧中取操作數(shù),對它們進(jìn)行操作,并把結(jié)果返回到棧中。選擇棧結(jié)構(gòu)的原因是:在只有少量寄存器或非通用寄存器的機(jī)器(如Intel486)上,也能夠高效地模擬Java虛擬機(jī)的行為。操作數(shù)棧是32位的。它用于給方法傳遞參數(shù),并從方法接收結(jié)果,也用于支持操作的參數(shù),并保存操作的結(jié)果。例如,iadd指令將兩個整數(shù)相加。相加的兩個整數(shù)應(yīng)該是操作數(shù)棧頂?shù)膬蓚€字。這兩個字是由先前的指令壓進(jìn)堆棧的。這兩個整數(shù)將從堆棧彈出、相加,并把結(jié)果壓回到操作數(shù)棧中。
每個原始數(shù)據(jù)類型都有專門的指令對它們進(jìn)行必須的操作。每個操作數(shù)在棧中需要一個存儲位置,除了long和double型,它們需要兩個位置。操作數(shù)只能被適用于其類型的操作符所操作。例如,壓入兩個int類型的數(shù),如果把它們當(dāng)作是一個long類型的數(shù)則是非法的。在Sun的Java虛擬機(jī)實(shí)現(xiàn)中,這個限制由字節(jié)碼驗(yàn)證器強(qiáng)制實(shí)行。但是,有少數(shù)操作(操作符dupe和swap),用于對運(yùn)行時數(shù)據(jù)區(qū)進(jìn)行操作時是不考慮類型的。
4.無用單元收集堆
Java的堆是一個運(yùn)行時數(shù)據(jù)區(qū),類的實(shí)例(對象)從中分配空間。Java語言具有無用單元收集能力:它不給程序員顯式釋放對象的能力。Java不規(guī)定具體使用的無用單元收集算法,可以根據(jù)系統(tǒng)的需求使用各種各樣的算法。
5.方法區(qū)
方法區(qū)與傳統(tǒng)語言中的編譯后代碼或是Unix進(jìn)程中的正文段類似。它保存方法代碼(編譯后的java代碼)和符號表。在當(dāng)前的Java實(shí)現(xiàn)中,方法代碼不包括在無用單元收集堆中,但計(jì)劃在將來的版本中實(shí)現(xiàn)。每個類文件包含了一個Java類或一個Java界面的編譯后的代碼??梢哉f類文件是Java語言的執(zhí)行代碼文件。為了保證類文件的平臺無關(guān)性,Java虛擬機(jī)規(guī)范中對類文件的格式也作了詳細(xì)的說明。其具體細(xì)節(jié)請參考Sun公司的Java虛擬機(jī)規(guī)范。
【編輯推薦】
- Java虛擬機(jī)概念及體系結(jié)構(gòu)
- 發(fā)現(xiàn)Java虛擬機(jī)內(nèi)存泄露問題
- 深入Java虛擬機(jī):JVM中的Stack和Heap
- Java虛擬機(jī)發(fā)展回顧 為跨平臺而生
- Java虛擬機(jī)(JVM)中的內(nèi)存設(shè)置詳解
當(dāng)前文章:Java虛擬機(jī)體系結(jié)構(gòu)
鏈接分享:http://www.dlmjj.cn/article/coesedj.html


咨詢
建站咨詢
