国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Java虛擬機的研究與實現

2019-11-18 13:58:14
字體:
來源:轉載
供稿:網友
摘 要 本文在研究kaffe的基礎上,吸收kaffe虛擬機的主要思想,用C語言作為開發語言,采用了及時編譯器作為執行引擎,實現了一種Windows平臺下的java虛擬機。然后對實現過程中的一些要害技術如class文件驗證、及時編譯器、垃圾收集器、線程同步和線程調度等做了分析。

  要害詞 kaffe; C語言; 及時編譯器;Java虛擬機

  引言

  Java虛擬機本質是就是一個程序,當它在命令行上啟動的時候,就開始執行保存在某字節碼文件中的指令。Java語言的可移植性正是建立在Java虛擬機的基礎上。任何平臺只要裝有針對于該平臺的Java虛擬機,字節碼文件(.class)就可以在該平臺上運行。這就是“一次編譯,多次運行”。

  kaffe虛擬機的簡要分析

  kaffe虛擬機采用了模塊化的程序設計思想,它由多個獨立的子系統組成。從功能模塊上來分它主要分為:虛擬機總體驅動模塊,類裝載器模塊,類執行模塊, 數據區治理模塊,內存治理模塊,本地支持模塊等等。kaffe虛擬機簡要的程序流程圖如圖1所示。

  Java虛擬機的研究與實現(圖一)
  圖1 kaffe虛擬機簡要的程序流程圖

  Java虛擬機的實現

  Java 源程序的執行過程為: Java源程序(.java)經過Java編譯器編譯生成字節碼文件(.class),然后由類裝載器將字節碼文件裝載到方法區中,然后進行連接驗證,由Java虛擬機讀取字節碼,轉換為特定平臺的指令,并且在對應的CPU中執行。

  本實現中采用的流程框架如下圖所示:

  Java虛擬機的研究與實現(圖二)
  圖2 本實現的主要框架

  1、類裝載、連接及初始化

  類文件包括:魔數(magic),次、主版本號,常量池,類或接口訪問修飾符,常量池索引(this_class和super_class),接口表,域表,方法表,類或接口的屬性信息。其中最復雜的內容是常量池,它類似于傳統語言編譯過程中用到的符號表。

  從原始的class文件到可以被Java虛擬機執行的內部數據格式,需要經過裝載、連接和初始化這3個階段。

  裝載是將class文件通過類裝載器裝載到在邏輯上被稱為方法區的內存單元中的過程。

  連接又分為三個步驟:驗證,預備和解析。驗證是對字節碼的驗證,可根據具體情況來確定被裝載的類是否符合Java虛擬機規范中規定的class文件格式,并確保它不會破壞Java虛擬機的完整性。包括(1)類裝載過程中的驗證; (2) 檢查class文件內部的連貫性,一旦發現class文件格式存在一處錯誤,則拋出VerifyError異?;駽lassFormatError異常。確保每個final類不含有子類,final方法不能被覆蓋,以及常量池中所有的域引用和方法引用有有效的名字和類型描述符號;(3) 對字節碼流使用一個數據流分析器進行驗證。預備步驟的任務是創建域表,并設置域初值。解析步驟是將類中的常量池中的類、接口、字段和方法的符號引用替換成直接引用,以達到更快地訪問數據的目的。

  在初始化階段,Java虛擬機設計者需要將類變量賦予正確的初始值。

  class文件經過上述三個階段的處理,虛擬機就獲得了該類的所有信息并且表示成能夠輕易操作的內部數據格式,從而為方法的運行作好了充分的預備。
  2、及時編譯器

  任何Java虛擬機實現的核心都是它的執行引擎。在由軟件實現的虛擬機中,執行引擎主要有一次性解釋字節碼、及時編譯器、自適應優化編譯器三種方式。本實現采用了及時編譯的方式,它的特點是第一次被執行的機器碼會被編譯成本地機器碼。及時編譯器將引入的字節碼翻譯成本地機器碼,然后直接執行機器碼指令而不是解釋字節碼。機器碼指令保存在內存中,由于在運行過程中編譯的結果不被保存, 所以程序下一次運行時,字節碼將再一次被翻譯成機器碼。

  假如一裝載完字節碼文件中的Java方法后,就對其進行編譯,則有點處理不恰當,因為還不清楚是否需要執行該方法。編譯一個不需要執行的方法,將帶來不必要的空間和時間上的損失。 因此虛擬機設計者需要采用一種優化方案,即只有需要被執行的方法才能被JIT編譯,這個問題可以參照kaffe虛擬機中的trampoline來解決。

  JIT實現步驟:(1)對字節碼進行驗證并且劃分基本塊;(2)產生四元式;(3)根據四元式生成本地機器碼;(4)操作數地址回填。

  Java虛擬機的研究與實現(圖三)
  圖3及時編譯器的流程圖

  在字節碼指令模擬操作的時候,按其語義動作生成指令屬性四元式序列,指令屬性四元式的結構為: (目的操作數, 源操作數1,源操作數2,語義動作),四元式數據結構如下:

typedef strUCt Sequence{
 void (*func)(struct Sequence*); //語義動作
 union{
  jvalue value;
  struct _label_ *labconst; //標號類型操作數
  Method *methconst; //方法地址操作數
  struct slotData **smask;
  struct slotData *slot; //槽操作數
 }u[3];
 uint8 type; //Sequence類型
 uint8 refered; //該四元式的引用
 struct Sequence *next; //下一個四元式
}Sequence;
  其中目的操作數為Sequence.u[0],源操作數1為Sequence.u[1],源操作數2為Sequence.u[2]。 Sequence.func則代表語義動作,它主要用于生成該Sequence語義的本地機器碼。

  指令屬性四元組建立后就進入代碼生成階段,屬性四元組在形式上已經非常接近本地機器指令,只需要遍歷該屬性序列,執行相應的語義動作函數,即可生成機器指令。語義動作函數的功能包括操作數尋址、寄存器分配、建立指令連接以及本地機器碼生成等。

  在及時編譯過程中要經常使用到操作數棧,虛擬機把操作數棧作為它的工作區。大多數指令都要從這里彈出數據,執行運算,然后把結果壓回操作數棧。而操作數棧區,局部變量區和幀數據區被包含在方法幀中。方法幀的數據結構如下:



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 沂水县| 行唐县| 大同县| 金堂县| 汶上县| 中方县| 衡阳市| 丹巴县| 贞丰县| 西峡县| 安新县| 双江| 曲靖市| 泰和县| 衡水市| 水城县| 当涂县| 鹿泉市| 富阳市| 崇阳县| 湘乡市| 万载县| 济阳县| 太和县| 德安县| 南靖县| 临邑县| 松江区| 怀安县| 荣昌县| 江陵县| 建湖县| 湟中县| 福鼎市| 久治县| 响水县| 吐鲁番市| 宁陕县| 隆德县| 将乐县| 富顺县|