<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Flyingis

    Talking and thinking freely !
    Flying in the world of GIS !
    隨筆 - 156, 文章 - 16, 評論 - 589, 引用 - 0
    數據加載中……

    Java虛擬機簡介[轉載]

    一、什么是Java虛擬機

     

    Java虛擬機是一個想象中的機器,在實際的計算機上通過軟件模擬來實現。Java虛擬機有自己想象中的硬件,如處理器、堆棧、寄存器等,還具有相應的指令系統。

     

    1.        為什么要使用Java虛擬機

    Java語言的一個非常重要的特點就是與平臺的無關性。而使用Java虛擬機是實現這一特點的關鍵。一般的高級語言如果要在不同的平臺上運行,至少需要編譯成不同的目標代碼。而引入Java語言虛擬機后,Java語言在不同平臺上運行時不需要重新編譯。Java語言使用模式Java虛擬機屏蔽了與具體平臺相關的信息,使得Java語言編譯程序只需生成在Java虛擬機上運行的目標代碼(字節碼),就可以在多種平臺上不加修改地運行。Java虛擬機在執行字節碼時,把字節碼解釋成具體平臺上的機器指令執行。

     

    2.        誰需要了解Java虛擬機

    Java虛擬機是Java語言底層實現的基礎,Java語言感興趣的人都應對Java虛擬機有個大概的了解。這有助于理解Java語言的一些性質,也有助于使用Java語言。對于要在特定平臺上實現Java虛擬機的軟件人員,Java語言的編譯器作者以及要用硬件芯片實現Java虛擬機的人來說,則必須深刻理解Java虛擬機的規范。另外,如果你想擴展Java語言,或是把其它語言編譯成Java語言的字節碼,你也需要深入地了解Java虛擬機。

     

    3.        Java虛擬機支持的數據類型

    Java虛擬機支持Java語言的基本數據類型如下:

     

    byte: 1字節有符號整數的補碼

    short: 2字節有符號整數的補碼

    int: 4字節有符號整數的補碼

    long: 8字節有符號整數的補碼

    float: 4字節IEEE754單精度浮點數

    double: 8字節IEEE754雙精度浮點數

    char: 2字節無符號Unicode字符

     

    幾乎所有的Java類型檢查都是在編譯時完成的。上面列出的原始數據類型的數據在Java執行時不需要用硬件標記。操作這些原始數據類型數據的字節碼(指令)本身就已經指出了操作數的數據類型,例如iaddladdfadddadd指令都是把兩個數相加,其操作數類型別是intlongfloatdouble。虛擬機沒有給boolean(布爾)類型設置單獨的指令。boolean型的數據是由integer指令,包括integer返回來處理的。boolean型的數組則是用byte數組來處理的。虛擬機使用IEEE754格式的浮點數。不支持IEEE格式的較舊的計算機,在運行Java數值計算程序時,可能會非常慢。

     

    虛擬機支持的其它數據類型包括:

    object: 對一個Javaobject(對象)4字節引用

    returnAddress: 4字節,用于jsr/ret/jsr-w/ret-w指令

    : Java數組被當作object處理。

     

    虛擬機的規范對于object內部的結構沒有任何特殊的要求。在Sun公司的實現中,object的引用是一個句柄,其中包含一對指針:一個指針指向該object的方法表,另一個指向該object的數據。用Java虛擬機的字節碼表示的程序應該遵守類型規定。Java虛擬機的實現應拒絕執行違反了類型規定的字節碼程序。Java虛擬機由于字節碼定義的限制似乎只能運行于32位地址空間的機器上。但是可以創建一個Java虛擬機,它自動地把字節碼轉換成64位的形式。從Java虛擬機支持的數據類型可以看出,Java對數據類型的內部格式進行了嚴格規定,這樣使得各種Java虛擬機的實現對數據的解釋是相同的,從而保證了Java的與平臺無關性和可移植性。

     

    二、Java虛擬機體系結構

     

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

     

    1.        Java指令集

    Java虛擬機支持大約248個字節碼。每個字節碼執行一種基本的CPU運算,例如,把一個整數加到寄存器,子程序轉移等。Java指令集相當于Java程序的匯編語言。

    Java指令集中的指令包含一個單字節的操作符,用于指定要執行的操作,還有0個或多個操作數,提供操作所需的參數或數據。許多指令沒有操作數,僅由一個單字節的操作符構成。

    虛擬機的內層循環的執行過程如下:

    do{

    取一個操作符字節;

    根據操作符的值執行一個動作;

    }while(程序未結束)

     

    由于指令系統的簡單性,使得虛擬機執行的過程十分簡單,從而有利于提高執行的效率。指令中操作數的數量和大小是由操作符決定的。如果操作數比一個字節大,那么它存儲的順序是高位字節優先。例如,一個16位的參數存放時占用兩個字節,其值為:

    第一個字節*256+第二個字節。

    字節碼指令流一般只是字節對齊的。指令tableswitchlookup是例外,在這兩條指令內部要求強制的4字節邊界對齊。

    2.        寄存器

    Java虛擬機的寄存器用于保存機器的運行狀態,與微處理器中的某些專用寄存器類似。

     

    Java虛擬機的寄存器有四種:

    pc:Java程序計數器。

    optop:指向操作數棧頂端的指針。

    frame:指向當前執行方法的執行環境的指針。

    vars:指向當前執行方法的局部變量區第一個變量的指針。

     

    Java虛擬機

    Java虛擬機是棧式的,它不定義或使用寄存器來傳遞或接受參數,其目的是為了保證指令集的簡潔性和實現時的高效性(特別是對于寄存器數目不多的處理器)。所有寄存器都是32位的。

     

    3.       

    Java虛擬機的棧有三個區域:局部變量區、運行環境區、操作數區。

     

    (1)局部變量區

    每個Jav方法使用一個固定大小的局部變量集。它們按照與vars寄存器的字偏移量來尋址。局部變量都是32位的。長整數和雙精度浮點數占據了兩個局部變量的空間,卻按照第一個局部變量的索引來尋址。(例如,一個具有索引n的局部變量,如果是一個雙精度浮點數,那么它實際占據了索引nn+1所代表的存儲空間。)虛擬機規范并不要求在局部變量中的64位的值是64位對齊的。虛擬機提供了把局部變量中的值裝載到操作數棧的指令,也提供了把操作數棧中的值寫入局部變量的指令。

     

    (2)運行環境區

    在運行環境中包含的信息用于動態鏈接,正常的方法返回以及異常傳播。

    ·

    動態鏈接

    運行環境包括對指向當前類和當前方法的解釋器符號表的指針,用于支持方法代碼的動態鏈接。方法的class文件代碼在引用要調用的方法和要訪問的變量時使用符號。動態鏈接把符號形式的方法調用翻譯成實際方法調用,裝載必要的類以解釋還沒有定義的符號,并把變量訪問翻譯成與這些變量運行時的存儲結構相應的偏移地址。動態鏈接方法和變量使得方法中使用的其它類的變化不會影響到本程序的代碼。

     

    正常的方法返回

    如果當前方法正常地結束了,在執行了一條具有正確類型的返回指令時,調用的方法會得到一個返回值。執行環境在正常返回的情況下用于恢復調用者的寄存器,并把調用者的程序計數器增加一個恰當的數值,以跳過已執行過的方法調用指令,然后在調用者的執行環境中繼續執行下去。

     

    異常和錯誤傳播

    異常情況在Java中被稱作Error(錯誤)Exception(異常),Throwable類的子類,在程序中的原因是:動態鏈接錯,如無法找到所需的class文件。運行時錯,如對一個空指針的引用程序使用了throw語句。當異常發生時,Java虛擬機采取如下措施:

    檢查與當前方法相聯系的catch子句表。每個catch子句包含其有效指令范圍,能夠處理的異常類型,以及處理異常的代碼塊地址。

    與異常相匹配的catch子句應該符合下面的條件:造成異常的指令在其指令范圍之內,發生的異常類型是其能處理的異常類型的子類型。如果找到了匹配的catch子句,那么系統轉移到指定的異常處理塊處執行;如果沒有找到異常處理塊,重復尋找匹配的catch子句的過程,直到當前方法的所有嵌套的catch子句都被檢查過。

    由于虛擬機從第一個匹配的catch子句處繼續執行,所以catch子句表中的順序是很重要的。因為Java代碼是結構化的,因此總可以把某個方法的所有的異常處理器都按序排列到一個表中,對任意可能的程序計數器的值,都可以用線性的順序找到合適的異常處理塊,以處理在該程序計數器值下發生的異常情況。

    如果找不到匹配的catch子句,那么當前方法得到一個"未截獲異常"的結果并返回到當前方法的調用者,好像異常剛剛在其調用者中發生一樣。如果在調用者中仍然沒有找到相應的異常處理塊,那么這種錯誤傳播將被繼續下去。如果錯誤被傳播到最頂層,那么系統將調用一個缺省的異常處理塊。

     

    (3)操作數棧區

    機器指令只從操作數棧中取操作數,對它們進行操作,并把結果返回到棧中。選擇棧結構的原因是:在只有少量寄存器或非通用寄存器的機器(Intel486),也能夠高效地模擬虛擬機的行為。操作數棧是32位的。它用于給方法傳遞參數,并從方法接收結果,也用于支持操作的參數,并保存操作的結果。例如,iadd指令將兩個整數相加。相加的兩個整數應該是操作數棧頂的兩個字。這兩個字是由先前的指令壓進堆棧的。這兩個整數將從堆棧彈出、相加,并把結果壓回到操作數棧中。

    每個原始數據類型都有專門的指令對它們進行必須的操作。每個操作數在棧中需要一個存儲位置,除了longdouble,它們需要兩個位置。操作數只能被適用于其類型的操作符所操作。例如,壓入兩個int類型的數,如果把它們當作是一個long類型的數則是非法的。在Sun的虛擬機實現中,這個限制由字節碼驗證器強制實行。但是,有少數操作(操作符dupeswap),用于對運行時數據區進行操作時是不考慮類型的。

     

    4.        無用單元收集堆

     

    Java的堆是一個運行時數據區,類的實例(對象)從中分配空間。Java語言具有無用單元收集能力:它不給程序員顯式釋放對象的能力。Java不規定具體使用的無用單元收集算法,可以根據系統的需求使用各種各樣的算法。

     

    5.        方法區

    方法區與傳統語言中的編譯后代碼或是Unix進程中的正文段類似。它保存方法代碼(編譯后的java代碼)和符號表。在當前的Java實現中,方法代碼不包括在無用單元收集堆中,但計劃在將來的版本中實現。每個類文件包含了一個Java類或一個Java界面的編譯后的代碼。可以說類文件是Java語言的執行代碼文件。為了保證類文件的平臺無關性,Java虛擬機規范中對類文件的格式也作了詳細的說明。其具體細節請參考Sun公司的Java虛擬機規范。

    posted on 2005-12-05 16:26 Flyingis 閱讀(493) 評論(0)  編輯  收藏 所屬分類: JavaSE

    主站蜘蛛池模板: 亚洲av午夜福利精品一区人妖| 亚洲国产成a人v在线观看 | 最新亚洲人成网站在线观看 | 免费看美女被靠到爽的视频| 性色av极品无码专区亚洲| 亚洲中文字幕伊人久久无码| 麻豆精品不卡国产免费看| 2020亚洲男人天堂精品| 亚洲精品国产精品国自产观看| 日韩视频在线观看免费| 亚洲va在线va天堂成人| 亚洲色一色噜一噜噜噜| 永久在线免费观看| 特级aaaaaaaaa毛片免费视频| 久久久久亚洲AV成人无码| 免费无码肉片在线观看| 国产黄色片免费看| 精品国产日韩久久亚洲| 国产av天堂亚洲国产av天堂| 青青青国产免费一夜七次郎| 久草视频在线免费看| 久久精品亚洲日本波多野结衣 | 国产产在线精品亚洲AAVV| 人人狠狠综合久久亚洲婷婷| 色www永久免费视频| 久久国产乱子伦免费精品| 亚洲免费一区二区| 亚洲国产午夜精品理论片在线播放| 久久精品视频亚洲| mm1313亚洲精品国产| 免费在线观看的网站| 无码av免费一区二区三区| 窝窝影视午夜看片免费| 国产成+人+综合+亚洲专| 国产aⅴ无码专区亚洲av| 亚洲av麻豆aⅴ无码电影| A级毛片内射免费视频| 桃子视频在线观看高清免费视频| 免费无码又爽又黄又刺激网站| 亚洲av一本岛在线播放| 亚洲成a人片77777老司机|