溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Java虛擬機(jī)有什么用

發(fā)布時(shí)間:2022-01-05 16:52:26 來(lái)源:億速云 閱讀:158 作者:小新 欄目:編程語(yǔ)言

這篇文章主要介紹Java虛擬機(jī)有什么用,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

一、 什么是Java虛擬機(jī)
Java虛擬機(jī)是一個(gè)想象中的機(jī)器,在實(shí)際的計(jì)算機(jī)上通過(guò)軟件模擬來(lái)實(shí)現(xiàn)。Java虛擬機(jī)有自己想象中的硬件,如處理器、堆棧、寄存器等,還具有相應(yīng)的指令系統(tǒng)。

1.為什么要使用Java虛擬機(jī)?

Java語(yǔ)言的一個(gè)非常重要的特點(diǎn)就是與平臺(tái)的無(wú)關(guān)性。而使用Java虛擬機(jī)是實(shí)現(xiàn)這一特點(diǎn)的關(guān)鍵。一般的高級(jí)語(yǔ)言如果要在不同的平臺(tái)上運(yùn)行, 至少需要編譯成不同的目標(biāo)代碼。而引入Java語(yǔ)言虛擬機(jī)后,Java語(yǔ)言在不同平臺(tái)上運(yùn)行時(shí)不需要重新編譯.

Java虛擬機(jī)屏蔽了與具體平臺(tái)相關(guān)的信息,使得Java語(yǔ)言編譯程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行。Java虛擬機(jī)在執(zhí)行字節(jié)碼時(shí),把字節(jié)碼解釋成具體平臺(tái)上的機(jī)器指令執(zhí)行。

2.誰(shuí)需要了解Java虛擬機(jī)


Java虛擬機(jī)是Java語(yǔ)言底層實(shí)現(xiàn)的基礎(chǔ),對(duì)Java語(yǔ)言感興趣的人都應(yīng)對(duì)Java虛擬機(jī)有個(gè)大概的了解。這有助于理解Java語(yǔ)言的一些性質(zhì),也有助于使用Java語(yǔ)言。
對(duì)于要在特定平臺(tái)上實(shí)現(xiàn)Java虛擬機(jī)的軟件人員,Java語(yǔ)言的編譯器作者以及要用硬件芯片實(shí)現(xiàn)Java虛擬機(jī)的人來(lái)說(shuō),則必須深刻理解Java虛擬機(jī)的規(guī)范。
另外,如果你想擴(kuò)展 Java語(yǔ)言,或是把其它語(yǔ)言編譯成Java語(yǔ)言的字節(jié)碼,你也需要深入地了解Java虛擬機(jī)。
3.Java虛擬機(jī)支持的數(shù)據(jù)類(lèi)型

Java虛擬機(jī)支持Java語(yǔ)言的基本數(shù)據(jù)類(lèi)型如下:

byte://1字節(jié)有符號(hào)整數(shù)的補(bǔ)碼 short://2字節(jié)有符號(hào)整數(shù)的補(bǔ)碼 int://4字節(jié)有符號(hào)整數(shù)的補(bǔ)碼 long://8字節(jié)有符號(hào)整數(shù)的補(bǔ)碼 float://4字節(jié)IEEE754單精度浮點(diǎn)數(shù) double://8字節(jié)IEEE754雙精度浮點(diǎn)數(shù) char://2字節(jié)無(wú)符號(hào)Unicode字符

幾乎所有的Java類(lèi)型檢查都是在編譯時(shí)完成的。上面列出的原始數(shù)據(jù)類(lèi)型的數(shù)據(jù)在 Java執(zhí)行時(shí)不需要用硬件標(biāo)記。操作這些原始數(shù)據(jù)類(lèi)型數(shù)據(jù)的字節(jié)碼(指令)本身就已經(jīng)指出了操作數(shù)的數(shù)據(jù)類(lèi)型,例如iadd、ladd、fadd和 dadd指令都是把兩個(gè)數(shù)相加,其操作數(shù)類(lèi)型特別是int、long、float和double。
虛擬機(jī)沒(méi)有給boolean(布爾)類(lèi)型設(shè)置單獨(dú)的指令。boolean型的數(shù)據(jù)是由integer指令, 包括integer返回來(lái)處理的。boolean型的數(shù)組則是用byte數(shù)組來(lái)處理的。
虛擬機(jī)使用IEEE754格式的浮點(diǎn)數(shù)。不支持IEEE格式的較舊的計(jì)算機(jī),在運(yùn)行Java數(shù)值計(jì)算程序時(shí),可能會(huì)非常慢。
虛擬機(jī)支持的其它數(shù)據(jù)類(lèi)型包括:

object//對(duì)一個(gè)Javaobject(對(duì)象)的4字節(jié)引用 returnAddress//4字節(jié),用于jsr/ret/jsr-w/ret-w指令

注:Java數(shù)組被當(dāng)作object處理。
虛擬機(jī)的規(guī)范對(duì)于object內(nèi)部的結(jié)構(gòu)沒(méi)有任何特殊的要求。在Sun公司的實(shí)現(xiàn)中,對(duì) object的引用是一個(gè)句柄,其中包含一對(duì)指針:一個(gè)指針指向該object的方法表,另一個(gè)指向 該object的數(shù)據(jù)。
用Java虛擬機(jī)的字節(jié)碼表示的程序應(yīng)該遵守類(lèi)型規(guī)定。Java虛擬機(jī)的實(shí)現(xiàn)應(yīng)拒絕執(zhí)行違反了類(lèi)型規(guī)定的字節(jié)碼程序。
Java虛擬機(jī)由于字節(jié)碼定義的限制似乎只能運(yùn)行于32位地址空間的機(jī)器上。但是可以創(chuàng)建一個(gè)Java虛擬機(jī),它自動(dòng)地把字節(jié)碼轉(zhuǎn)換成64位的形式。
從Java虛擬機(jī)支持的數(shù)據(jù)類(lèi)型可以看出,Java對(duì)數(shù)據(jù)類(lèi)型的內(nèi)部格式進(jìn)行了嚴(yán)格規(guī)定,這樣使得各種Java虛擬機(jī)的實(shí)現(xiàn)對(duì)數(shù)據(jù)的解釋是相同的,從而保證了Java的與平臺(tái)無(wú)關(guān)性和可移植性。
二、 Java虛擬機(jī)體系結(jié)構(gòu)

Java虛擬機(jī)由五個(gè)部分組成:一組指令集、一組寄存器、一個(gè)棧、一個(gè)無(wú)用單元收集堆(Garbage-collected-heap)、一個(gè)方法區(qū)域。這五部分是Java虛擬機(jī)的邏輯成份,不依賴(lài) 任何實(shí)現(xiàn)技術(shù)或組織方式,但它們的功能必須在真實(shí)機(jī)器上以某種方式實(shí)現(xiàn)。

Java指令集
Java虛擬機(jī)支持大約248個(gè)字節(jié)碼。每個(gè)字節(jié)碼執(zhí)行一種基本的CPU運(yùn)算,例如,把一個(gè)整數(shù)加到寄存器,子程序轉(zhuǎn)移等。Java指令集相當(dāng)于Java程序的匯編語(yǔ)言。
Java指令集中的指令包含一個(gè)單字節(jié)的操作符,用于指定要執(zhí)行的操作,還有0個(gè)或多個(gè)操作數(shù),提供操作所需的參數(shù)或數(shù)據(jù)。許多指令沒(méi)有操作數(shù),僅由一個(gè)單字節(jié)的操作符構(gòu)成。虛擬機(jī)的內(nèi)層循環(huán)的執(zhí)行過(guò)程如下:
do{ 取一個(gè)操作符字節(jié); 根據(jù)操作符的值執(zhí)行一個(gè)動(dòng)作; }while(程序未結(jié)束)

由于指令系統(tǒng)的簡(jiǎn)單性,使得虛擬機(jī)執(zhí)行的過(guò)程十分簡(jiǎn)單,從而有利于提高執(zhí)行的效率。
指令中操作數(shù)的數(shù)量和大小是由操作符決定的。如果操作數(shù)比一個(gè)字節(jié)大,那么它存儲(chǔ)的順序是高位字節(jié)優(yōu)先。例如,一個(gè)16位的參數(shù)存放時(shí)占用兩個(gè)字節(jié),其值為: 第一個(gè)字節(jié)*256+第二個(gè)字節(jié)
字節(jié)碼指令流一般只是字節(jié)對(duì)齊的。指令tableswitch和lookup是例外,在這兩條指令內(nèi)部 要求強(qiáng)制的4字節(jié)邊界對(duì)齊。

寄存器
Java虛擬機(jī)的寄存器用于保存機(jī)器的運(yùn)行狀態(tài),與微處理器中的某些專(zhuān)用寄存器類(lèi)似。 Java虛擬機(jī)的寄存器有四種:
pc:Java程序計(jì)數(shù)器。 optop:指向操作數(shù)棧頂端的指針。 frame:指向當(dāng)前執(zhí)行方法的執(zhí)行環(huán)境的指針。 vars:指向當(dāng)前執(zhí)行方法的局部變量區(qū)第一個(gè)變量的指針。


Java虛擬機(jī)
Java虛擬機(jī)是棧式的,它不定義或使用寄存器來(lái)傳遞或接受參數(shù),其目的是為了保證指令集的簡(jiǎn)潔性和實(shí)現(xiàn)時(shí)的高效性(特別是對(duì)于寄存器數(shù)目不多的處理器)。所有寄存器都是32位的。


Java虛擬機(jī)的棧有三個(gè)區(qū)域:局部變量區(qū)、運(yùn)行環(huán)境區(qū)、操作數(shù)區(qū)。
局部變量區(qū) 
每個(gè)Java方法使用一個(gè)固定大小的局部變量集。它們按照與vars寄存器的字偏移量來(lái)尋址。局部變量都是32位的。長(zhǎng)整數(shù)和雙精度浮點(diǎn)數(shù)占據(jù)了兩個(gè)局部變量的空間,卻按照第一個(gè)局部變量的索引來(lái)尋址。(例如,一個(gè)具有索引n的局部變量,如果是一個(gè)雙精度浮點(diǎn)數(shù),那么它實(shí)際占據(jù)了索引 n和n+1所代表的存儲(chǔ)空間。)虛擬機(jī)規(guī)范并不要求在局部變量中的64位的值是64位對(duì)齊的虛擬機(jī)提供了把局部變量中的值裝載到操作數(shù)棧的指令,也提供了把操作數(shù)棧中的值寫(xiě)入局部變量的指令。
運(yùn)行環(huán)境區(qū)
 在運(yùn)行環(huán)境中包含的信息用于動(dòng)態(tài)鏈接,正常的方法返回以及異常傳播。
動(dòng)態(tài)鏈接
運(yùn)行環(huán)境包括對(duì)指向當(dāng)前類(lèi)和當(dāng)前方法的解釋器符號(hào)表的指針,用于支持方法代碼的動(dòng)態(tài)鏈接。方法的class文件代碼在引用要調(diào)用的方法和要訪問(wèn)的變量時(shí)使用符號(hào)。動(dòng)態(tài)鏈接把符號(hào)形式的方法調(diào)用翻譯成實(shí)際方法調(diào)用,裝載必要的類(lèi)以解釋還沒(méi)有定義的符號(hào), 并把變量訪問(wèn)翻譯成與這些變量運(yùn)行時(shí)的存儲(chǔ)結(jié)構(gòu)相應(yīng)的偏移地址。動(dòng)態(tài)鏈接方法和變量使得方法中使用的其它類(lèi)的變化不會(huì)影響到本程序的代碼。
正常的方法返回
如果當(dāng)前方法正常地結(jié)束了,在執(zhí)行了一條具有正確類(lèi)型的返回指令時(shí),調(diào)用的方法會(huì)得到一個(gè)返回值。
執(zhí)行環(huán)境在正常返回的情況下用于恢復(fù)調(diào)用者的寄存器,并把調(diào)用者的程序計(jì)數(shù)器增加一個(gè)恰當(dāng)?shù)臄?shù)值,以跳過(guò)已執(zhí)行過(guò)的方法調(diào)用指令,然后在調(diào)用者的執(zhí)行環(huán)境中繼續(xù)執(zhí)行下去。

異常和錯(cuò)誤傳播
異常情況在Java中被稱(chēng)作Error(錯(cuò)誤)或Exception(異常),是Throwable類(lèi)的子類(lèi),在程序中出錯(cuò)的原因是:①動(dòng)態(tài)鏈接錯(cuò),如無(wú)法找到所需的class文件。②運(yùn)行時(shí)錯(cuò),如對(duì)一個(gè)空指針的引用

程序使用了throw語(yǔ)句。
當(dāng)異常發(fā)生時(shí),Java虛擬機(jī)采取如下措施:
檢查與當(dāng)前方法相聯(lián)系的catch子句表。每個(gè)catch子句包含其有效指令范圍,能夠處理的異常類(lèi)型,以及處理異常的代碼塊地址。
與異常相匹配的catch子句應(yīng)該符合下面的條件:造成異常的指令在其指令范圍之內(nèi) ,發(fā)生的異常類(lèi)型是其能處理的異常類(lèi)型的子類(lèi)型。如果找到了匹配的catch子句,那么系統(tǒng)轉(zhuǎn)移到指定的異常處理塊處執(zhí)行;如果沒(méi)有找到異常處理塊,重復(fù)尋找匹配的catch子句的過(guò)程,直到當(dāng)前方法的所有嵌套的catch子句都被檢查過(guò)。
由于虛擬機(jī)從第一個(gè)匹配的catch子句處繼續(xù)執(zhí)行,所以catch子句表中的順序是很重要的。因?yàn)镴ava代碼是結(jié)構(gòu)化的,因此總可以把某個(gè)方法的所有的異常處理器都按序排列到一個(gè)表中,對(duì)任意可能的程序計(jì)數(shù)器的值,都可以用線性的順序找到合適的異常處理塊,以處理在該程序計(jì)數(shù)器值下發(fā)生的異常情況。
如果找不到匹配的catch子句,那么當(dāng)前方法得到一個(gè)"未截獲異常"的結(jié)果并返回到當(dāng)前方法的調(diào)用者,好像異常剛剛在其調(diào)用者中發(fā)生一樣。如果在調(diào)用者中仍然沒(méi)有找到相應(yīng)的異常處理,那么系 統(tǒng)將調(diào)用一個(gè)缺省的異常處理塊。
操作數(shù)棧區(qū) 
機(jī)器指令只從操作數(shù)棧中取操作數(shù),對(duì)它們進(jìn)行操作,并把結(jié)果返回到棧中。選擇棧結(jié)構(gòu)的原因是:在只有少量寄存器或非通用寄存器的機(jī)器(如Intel486)上,也能夠高效地模擬虛擬機(jī)的行為。
操作數(shù)棧是32位的。它用于給方法傳遞參數(shù),并從方法接收結(jié)果,也用于支持操作的參數(shù),并保存操作的結(jié)果。
例如,iadd指令將兩個(gè)整數(shù)相加。相加的兩個(gè)整數(shù)應(yīng)該是操作數(shù)棧頂?shù)膬蓚€(gè)字。這兩個(gè)字是由先前的指令壓進(jìn)堆棧的。這兩個(gè)整數(shù)將從堆棧彈出、相加,并把結(jié)果壓回到操作數(shù)棧中。每個(gè)原始數(shù)據(jù)類(lèi)型都有專(zhuān)門(mén)的指令對(duì)它們進(jìn)行必須的操作。每個(gè)操作數(shù)在棧中需要一個(gè)存儲(chǔ)位置,除了long和double 型,它們需要兩個(gè)位置。
操作數(shù)只能被適用于其類(lèi)型的操作符所操作。例如,壓入兩個(gè)int類(lèi)型的數(shù),如果把它們當(dāng)作是一個(gè)long類(lèi)型的數(shù)則是非法的。在Sun的虛擬機(jī)實(shí)現(xiàn)中,這個(gè)限制由字節(jié)碼驗(yàn)證器強(qiáng)制實(shí)行。但是,有少數(shù)操作(操作符dupe和swap),用于對(duì)運(yùn)行時(shí)數(shù)據(jù)區(qū)進(jìn)行操作時(shí)是不考慮類(lèi)型的。
無(wú)用單元收集堆
Java的堆是一個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū),類(lèi)的實(shí)例(對(duì)象)從中分配空間。Java語(yǔ)言具有無(wú)用單元收集能力:它不給程序員顯式釋放對(duì)象的能力。Java不規(guī)定具體使用的無(wú)用單元收集算法,可以根據(jù)系統(tǒng)的需求使用各種各樣的算法。

方法區(qū)
方法區(qū)與傳統(tǒng)語(yǔ)言中的編譯后代碼或是Unix進(jìn)程中的正文段類(lèi)似。它保存方法代碼 (編譯后的java代碼)和符號(hào)表。在當(dāng)前的Java實(shí)現(xiàn)中,方法代碼不包括在無(wú)用單元收集堆中,但計(jì)劃在將來(lái)的版本中實(shí)現(xiàn)。每個(gè)類(lèi)文件包含了一個(gè) Java類(lèi)或一個(gè)Java界面的編譯后的代碼??梢哉f(shuō)類(lèi)文件是 Java語(yǔ)言的執(zhí)行代碼文件。為了保證類(lèi)文件的平臺(tái)無(wú)關(guān)性,Java虛擬機(jī)規(guī)范中對(duì)類(lèi)文件的格式也作了詳細(xì)的說(shuō)明。其具體細(xì)節(jié)請(qǐng)參考Sun公司的Java 虛擬機(jī)規(guī)范
三、 Java類(lèi)文件(.class文件)

每個(gè)類(lèi)文件包含了一個(gè)Java類(lèi)或一個(gè)Java界面的編譯后的代碼。可以說(shuō)類(lèi)文件是Java語(yǔ)言的執(zhí)行代碼文件。為了保證類(lèi)文件的平臺(tái)無(wú)關(guān)性,Java虛擬機(jī)規(guī)范中對(duì)類(lèi)文件的格式也作了詳細(xì)的說(shuō)明。其具體細(xì)節(jié)請(qǐng)參考Sun公司的Java虛擬機(jī)規(guī)范。

四、 Java芯片

由于Java語(yǔ)言是解釋型語(yǔ)言,在一般的通用處理器上其運(yùn)行速度比起編譯型語(yǔ)言要慢很多。Sun公司為了進(jìn)一步推廣Java的應(yīng)用,推出了 Java芯片。這些芯片可以說(shuō)是Java虛擬機(jī)的硬件實(shí)現(xiàn)。與通用芯片和解釋器構(gòu)成的虛擬機(jī)不同,Java芯片可以直接執(zhí)行字節(jié)碼,也就是說(shuō),字節(jié)碼就是 Java芯片的指令集。這種用硬件實(shí)現(xiàn)的虛擬機(jī)當(dāng)然要比軟件模擬的虛擬機(jī)的速度要快得多。
Sun公司計(jì)劃推出的Java芯片有三種:picoJava,mi-croJava和ultraJava。

picoJava是一個(gè)很小的Java內(nèi)核芯片,其硅片面積只有25mm2。Sun公司準(zhǔn)備向其它公司轉(zhuǎn)讓,以便其它公司可以定制自己的Java芯片,其低端產(chǎn)品的售價(jià)估計(jì)不到25美元。
microJava是基于picoJava的微控制器芯片,其芯片面積約為50mm2,用于通信設(shè)備和其它嵌入式控制設(shè)備。Sun公司希望Java芯片可以成為推動(dòng)Java發(fā)展的主要技術(shù)之一。

以上是“Java虛擬機(jī)有什么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI