Java虛擬機(jī)的設(shè)計(jì)和實(shí)現(xiàn)_第1頁(yè)
Java虛擬機(jī)的設(shè)計(jì)和實(shí)現(xiàn)_第2頁(yè)
Java虛擬機(jī)的設(shè)計(jì)和實(shí)現(xiàn)_第3頁(yè)
已閱讀5頁(yè),還剩43頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Java虛擬機(jī)的設(shè)計(jì)和實(shí)現(xiàn)第一章緒論6Java及Java虛擬機(jī)6.Java虛擬機(jī)的體系結(jié)構(gòu)7.MiniJavaVM的功能10MiniJavaVM的運(yùn)行環(huán)境及開(kāi)發(fā)工具2系統(tǒng)設(shè)計(jì)132.1 唯一的虛擬機(jī)MiniJavaVM13MiniJavaVM的構(gòu)成要素1.3虛擬機(jī)總體框架13命令參數(shù)解析模塊15類(lèi)的裝載和解析模塊1522J內(nèi)存管理模塊16執(zhí)行引擎模塊17方法調(diào)用模塊18異常處理模塊19第三章虛擬機(jī)框架的實(shí)現(xiàn)213.1 JVM工程223.2.1 JavaVM工程23Java虛擬機(jī)的數(shù)據(jù)類(lèi)型和字長(zhǎng)考量23JavaVM類(lèi)24JavaNativeCall工程29第四章類(lèi)的裝載和解析304.1 Java

2、Class文件304.2 Class文件在MiniJavaVM中的數(shù)據(jù)結(jié)構(gòu)表示32類(lèi)的裝載和IS析36第五章內(nèi)存管理415.1 對(duì)象、堆、方法區(qū)的管理41MiniJavaVM44第六章執(zhí)行引擎一一Java操作碼實(shí)現(xiàn)476.1 Java虛擬機(jī)中的操作碼功能分類(lèi)47操作碼功能實(shí)現(xiàn)JavaOperatorExecute類(lèi)49第七章方法調(diào)用的實(shí)現(xiàn)507.1 Java中的方法調(diào)用507.2 非本地方法的實(shí)現(xiàn)5.17J本地方法的實(shí)現(xiàn)52Java中的本地方法52NativeMethod_access類(lèi)54如何處理本地,方法可如參數(shù)問(wèn)木54第八章異常的實(shí)現(xiàn)568.1 Java中的異常5682異常在MiniJa

3、vaVM中的實(shí)現(xiàn)56第九章驗(yàn)證MiniJavaVM的正確性589.1 MiniJavaVM的使用方法589.2.1 測(cè)試操作碼實(shí)現(xiàn)的正確性.6.1方法調(diào)用的正確性61數(shù)學(xué)運(yùn)算的正確性64控制流語(yǔ)句的正確性659.2 測(cè)試本地方法調(diào)用66測(cè)試異常處理67第十章不足與后續(xù)工作6910.1 本地方法6910.2 I/O操作6910.3 多線程.69效率69致謝71參考文獻(xiàn)72摘要本文敘述了Java虛擬機(jī)(JVM)的概念及如何設(shè)計(jì)和實(shí)現(xiàn)一個(gè)Java虛擬機(jī)MiniJavaVM。著重介紹了虛擬機(jī)的體系結(jié)構(gòu)及如何設(shè)計(jì)和實(shí)現(xiàn)這個(gè)體系結(jié)構(gòu)。在探討虛擬機(jī)的設(shè)計(jì)過(guò)程中詳細(xì)介紹了MiniJavaVM虛擬機(jī)各部分的設(shè)計(jì)

4、,包括類(lèi)的裝載和解析,內(nèi)存管理,執(zhí)行引擎,方法調(diào)用和異常處理部分。最后通過(guò)測(cè)試MiniJavaVM來(lái)驗(yàn)證設(shè)計(jì)和實(shí)現(xiàn)的正確性。關(guān)鍵詞Java虛擬機(jī)(JVM)字節(jié)碼類(lèi)裝載執(zhí)行引擎本地方法MiniJavaVM-adesignandimplementationofaJavaVirtualMachineAbstractThispaperdescribestheconceptionofJavaVirtualMachine(JVM)andhowtodesignandimplementaJavaVirtualMachine-MiniJavaVM.ItemphasizesthearchitectureofJVM

5、andhowtodesignandimplementthearchitecture.ItdescribesthedetailsabouteachpartofJVMwhendiscussinghowtodesigntheJVM,includingclass-loadingandresolution,memorymanagement,executionengine,methodinvokingandexception-handling.Atlast,thecorrectnessofthedesignandimplementationisvalidatedbytestingMiniJavaVM.Ke

6、ywordsJavaVirtualMachine(JVM),bytecode,Class-loading,executionengine,NativeMethod.第一章緒論1.1 Java及Java虛擬機(jī)說(shuō)起Java,人們首先想到的是Java編程語(yǔ)言,然而事實(shí)上,Java是一種技術(shù),它由四方面組成:Java編程語(yǔ)言、Java類(lèi)文件格式、Java虛擬機(jī)和Java應(yīng)用程序接口(JavaAPI)。它們的關(guān)系如下圖所示:1J號(hào)虛擬機(jī)圖1.1.1Java四個(gè)方面的關(guān)系運(yùn)行期環(huán)境代表著Java平臺(tái),開(kāi)發(fā)人員編寫(xiě)Java代碼(.java文件),然后將之編譯成字節(jié)碼(.class文件)。最后字節(jié)碼被裝入內(nèi)存

7、,一旦字節(jié)碼進(jìn)入虛擬機(jī),它就會(huì)被解釋器解釋執(zhí)行,或者是被即時(shí)代碼發(fā)生器有選擇的轉(zhuǎn)換成機(jī)器碼執(zhí)行。從上圖也可以看出Java平臺(tái)由Java虛擬機(jī)和Java應(yīng)用程序接口搭建,Java語(yǔ)言則是進(jìn)入這個(gè)平臺(tái)的通道,用Java語(yǔ)言編寫(xiě)并編譯的程序可以運(yùn)行在這個(gè)平臺(tái)上。這個(gè)平臺(tái)的結(jié)構(gòu)如下圖所示:1應(yīng)用程序和小應(yīng)用程序“餌基本API怕標(biāo)準(zhǔn)擴(kuò)展APIJava標(biāo)準(zhǔn)擴(kuò)展美Java虛擬機(jī)稼棺會(huì)口適配器適配器適配器Java噪作汞貌倒覽器系統(tǒng)麋作系貌硬件一硬件硬件瀏1覽器上的用能桌面操作系藐上的Java小型操作系統(tǒng)上的JavaJava操作系舞的Java圖1.1.2Javsff臺(tái)結(jié)構(gòu)在Java平臺(tái)的結(jié)構(gòu)中,可以看出,Jav

8、a虛擬機(jī)(JVM)處在核心的位置,是程序與底層操作系統(tǒng)和硬件無(wú)關(guān)的關(guān)鍵。它的下方是移植接口,移植接口由兩部分組成:適配器和Java操作系統(tǒng),其中依賴(lài)于平臺(tái)的部分稱(chēng)為適配器;JVM通過(guò)移植接口在具體的平臺(tái)和操作系統(tǒng)上實(shí)現(xiàn);在JVM的上方是Java的基本類(lèi)庫(kù)和擴(kuò)展類(lèi)庫(kù)以及它們的API,利用JavaAPI編寫(xiě)的應(yīng)用程序(application)和小程序(Javaapplet)可以在任何Java平臺(tái)上運(yùn)行而無(wú)需考慮底層平臺(tái),就是因?yàn)橛蠮ava虛擬機(jī)(JVM)實(shí)現(xiàn)了程序與操作系統(tǒng)的分離,從而實(shí)現(xiàn)了Java的平臺(tái)無(wú)關(guān)性。1什么是Java虛擬機(jī)?Java虛擬機(jī)是運(yùn)行所有Java程序的抽象計(jì)算機(jī),它僅僅是由一

9、個(gè)規(guī)范來(lái)定義的抽象的計(jì)算機(jī)。當(dāng)提及“Java虛擬機(jī)”時(shí),可能指的是如下三種不同的東西:抽象規(guī)范一個(gè)具體的實(shí)現(xiàn)一個(gè)運(yùn)行中的虛擬機(jī)實(shí)例2Java虛擬機(jī)負(fù)責(zé)Java程序設(shè)計(jì)語(yǔ)言的內(nèi)存安全、平臺(tái)無(wú)關(guān)和安全特性。Java虛擬機(jī)屏蔽了與具體操作系統(tǒng)平臺(tái)相關(guān)的信息,使得Java語(yǔ)言編譯程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行。Java虛擬機(jī)(JVM)在多個(gè)平臺(tái)上實(shí)現(xiàn)統(tǒng)一語(yǔ)言。Java之所以得以大行其道,除了它是一門(mén)面向?qū)ο?、?gòu)造精美的語(yǔ)言之外,更重要的原因在于:它擺脫了具體機(jī)器的束縛,使跨越不同平臺(tái)編寫(xiě)程序成為可能。1.2 Java虛擬機(jī)的體系結(jié)構(gòu)在Java虛

10、擬機(jī)規(guī)范中,一個(gè)虛擬機(jī)實(shí)例的行為是分別按照子系統(tǒng)、內(nèi)存區(qū)、數(shù)據(jù)類(lèi)型以及指令這幾個(gè)術(shù)語(yǔ)來(lái)描述的。這些組成部分一起展示了抽象的虛擬機(jī)的內(nèi)部抽象體系結(jié)構(gòu)。但是規(guī)范中對(duì)它們的定義并非是要強(qiáng)制規(guī)定Java虛擬機(jī)實(shí)現(xiàn)內(nèi)部的體系結(jié)構(gòu),更多的是為了嚴(yán)格地定義這些實(shí)現(xiàn)的內(nèi)部特征。規(guī)范本身通過(guò)定義這些抽象的組成部分以及它們之間的交互,來(lái)定義任何Java虛擬機(jī)實(shí)現(xiàn)都必須遵守的行為。每個(gè)JVM都有兩種機(jī)制,一個(gè)是裝載具有合適名稱(chēng)的類(lèi)(類(lèi)或是接口),叫做類(lèi)裝載子系統(tǒng);另外的一個(gè)負(fù)責(zé)執(zhí)行包含在已裝載的類(lèi)或接口中的指令,叫做運(yùn)行引擎。每個(gè)JVM又包括方法區(qū)、堆、Java棧、程序計(jì)數(shù)器和本地方法棧這五個(gè)部分,這幾個(gè)部分和類(lèi)裝

11、載機(jī)制與運(yùn)行引擎機(jī)制一起組成了Java虛擬機(jī)的體系結(jié)構(gòu)。圖1.2.1描述了Java虛擬機(jī)的結(jié)構(gòu)框圖,包括在規(guī)范中描述的主要子系統(tǒng)和內(nèi)存區(qū)。Class文件本地方法接口本地方法庫(kù)圖1.2.1Javs擬機(jī)的內(nèi)部體系結(jié)構(gòu)每個(gè)Java虛擬機(jī)都有一個(gè)類(lèi)裝載器子系統(tǒng),它根據(jù)給定的全限定名來(lái)裝入類(lèi)型(類(lèi)或接口)。同樣,每個(gè)Java虛擬機(jī)都有一個(gè)執(zhí)行引擎,它負(fù)責(zé)執(zhí)行那些包含在被裝載類(lèi)的方法中的指令。Java虛擬機(jī)的運(yùn)行時(shí)數(shù)據(jù)區(qū)存儲(chǔ)了許多運(yùn)行時(shí)數(shù)據(jù),例如,字節(jié)碼,從已裝載的class文件中得到的其他信息,程序創(chuàng)建的對(duì)象,傳遞給方法的參數(shù),返回值,局部變量,以及運(yùn)算的中間結(jié)果等。Java虛擬機(jī)把這些東西都組織到幾個(gè)

12、“運(yùn)行時(shí)數(shù)據(jù)區(qū)”中,以便于管理。某些運(yùn)行時(shí)數(shù)據(jù)區(qū)是由程序中所有線程共享的,還有一些則只能由一個(gè)線程擁有。每個(gè)Java虛擬機(jī)實(shí)例都有一個(gè)方法區(qū)及一個(gè)堆,它們是由該虛擬機(jī)實(shí)例中所有線程共享的。當(dāng)虛擬機(jī)裝載一個(gè)class文件時(shí),它會(huì)從這個(gè)class文件包含的二進(jìn)制數(shù)據(jù)中解析類(lèi)型信息。然后把這些類(lèi)型信息放到方法區(qū)中。當(dāng)程序運(yùn)行時(shí),虛擬機(jī)會(huì)把所有該程序在運(yùn)行時(shí)創(chuàng)建的對(duì)象都放到堆中。圖1.2.2描述了這些內(nèi)存區(qū)域。I對(duì)象(對(duì)象圖1.2.2由所有線程共享的運(yùn)行時(shí)數(shù)據(jù)區(qū)當(dāng)每一個(gè)線程被創(chuàng)建時(shí),它都將得到它自己的PC寄存器以及一個(gè)Java棧。如果線程正在執(zhí)行的是一個(gè)Java方法(非本地方法),那么PC寄存器的值將

13、總是指示下一條將被執(zhí)行的指令,而它的Java棧則總是存儲(chǔ)該線程中Java方法調(diào)用的狀態(tài)一一包括它的局部變量,被調(diào)用時(shí)傳進(jìn)來(lái)的參數(shù),它的返回值,以及運(yùn)算的中間結(jié)果等。而本地方法調(diào)用的狀態(tài),則是以某種依賴(lài)于具體實(shí)現(xiàn)的方式存儲(chǔ)在本地方法棧中,也可能是在寄存器或其他某些與特定實(shí)現(xiàn)相關(guān)的內(nèi)存區(qū)中。Java棧是由許多棧幀(stackframe)組成的,一個(gè)棧幀包含一個(gè)Java方法調(diào)用的狀態(tài)。當(dāng)線程調(diào)用一個(gè)Java方法時(shí),虛擬機(jī)壓入一個(gè)新的棧幀到該線程的Java棧中;當(dāng)該方法返回時(shí),這個(gè)棧幀被從Java棧中彈出并拋棄。Java虛擬機(jī)沒(méi)有寄存器,其指令集使用Java棧來(lái)存儲(chǔ)中間數(shù)據(jù)。這樣設(shè)計(jì)的原因是為了保持J

14、ava虛擬機(jī)的指令集盡量緊湊,同時(shí)也便于Java虛擬機(jī)在那些只有很少通用寄存器的平臺(tái)上實(shí)現(xiàn)。另外,Java虛擬機(jī)的這種基于棧的體系結(jié)構(gòu),也有助于運(yùn)行時(shí)某些虛擬機(jī)實(shí)現(xiàn)的動(dòng)態(tài)編譯器和即時(shí)編譯器的代碼優(yōu)化。圖1.2.3描繪了Java虛擬機(jī)為每個(gè)線程創(chuàng)建的內(nèi)存區(qū),這些內(nèi)存區(qū)是私有的,任何線程都不能訪問(wèn)另一個(gè)線程的PC寄存器或者Java棧。3線程3PC寄存器1.3MiniJavaVM線程1棧幀棧幀棧幀棧幀線程2棧幀棧幀棧幀Jav哦線程3線程3棧幀棧幀本地方法棧圖1.2.3線程專(zhuān)有的運(yùn)行時(shí)數(shù)據(jù)區(qū)的功能能夠裝載并解析javaclass文件對(duì)于已經(jīng)編譯好的javaclass文件,能夠讀取該class文件的內(nèi)容

15、,裝載該類(lèi),并保存在程序內(nèi)部的數(shù)據(jù)結(jié)構(gòu)中。當(dāng)在程序運(yùn)行的過(guò)程中需要解析該類(lèi)時(shí),進(jìn)行解析,并替換符號(hào)引用為直接引用在完成虛擬機(jī)的初始化后,能夠找到main函數(shù)并執(zhí)行程序錯(cuò)誤!未定義書(shū)簽。main()方法,如果找到,對(duì)于指定的入口類(lèi),在虛擬機(jī)完成了初始化后,尋找該類(lèi)的則執(zhí)行該方法,否則拋出異常,虛擬機(jī)運(yùn)行中止。支持Java虛擬機(jī)規(guī)范中規(guī)定的200多個(gè)操作碼的功能實(shí)現(xiàn)了Java虛擬機(jī)的200多個(gè)操作碼的功能,由此使MiniJavaVM這個(gè)虛擬機(jī)模擬Java虛擬機(jī)的功能成為可能,這200多個(gè)操作碼包括:棧和局部變量操作指令?將常量池入指令?從棧中的局部變量中裝載值指令?將棧中的值存入局部變量指令?通用

16、棧操作指令類(lèi)型轉(zhuǎn)換指令整數(shù)運(yùn)算指令邏輯運(yùn)算指令?移位操作指令按位布爾運(yùn)算指令浮點(diǎn)運(yùn)算指令?對(duì)象和數(shù)組指令?對(duì)象操作指令?數(shù)組操作指令?控制流指令?條件分支指令?比較指令?無(wú)條件轉(zhuǎn)移指令?表跳轉(zhuǎn)指令?異常指令?finally子句指令?方法調(diào)用與返回指令?方法調(diào)用指令?方法返回指令?線程同步指令具有內(nèi)存管理和垃圾收集機(jī)制Java虛擬機(jī)對(duì)內(nèi)存的管理使得java程序具有很高的安全性,程序員不用擔(dān)心內(nèi)存訪問(wèn)越界問(wèn)題,也不用為在合適的時(shí)候釋放分配的空間而費(fèi)心。垃圾收集機(jī)制的存在解決何時(shí)回收不用的內(nèi)存和如何回收內(nèi)存的問(wèn)題。支持非本地方法調(diào)用按照J(rèn)ava虛擬機(jī)規(guī)范中的要求來(lái)設(shè)置非本地方法的調(diào)用情況,包括參數(shù)壓

17、棧,分配局部變量空間,壓入方法調(diào)用的棧楨等。支持本地方法調(diào)用Java虛擬機(jī)中所有與本地方法相關(guān)的部分都重新寫(xiě)過(guò),以動(dòng)態(tài)鏈接庫(kù)的形式為MiniJavaVM工程提供支持。MiniJavaVM的本地方法只實(shí)現(xiàn)最基本的功能,不再負(fù)責(zé)虛擬機(jī)的安全機(jī)制。支持異常處理有了異常處理,就能夠在程序運(yùn)行時(shí)平穩(wěn)處理意外情況。根據(jù)Javaclass文件中的異常表,MiniJavaVM程序支持所有的異常處理,并在不能解決異常時(shí)輸出異常信息,虛擬機(jī)停止運(yùn)行。能夠運(yùn)行與I/O無(wú)關(guān)的完整Java程序,并提供參數(shù)供查看運(yùn)行效果提供了-version,-showversion,-help,-?,-verbose命令。-versi

18、on命令顯示MiniJavaVM的版本信息,然后退出-showversion命令顯示MiniJavaVM的版本信息,然后繼續(xù)運(yùn)行Java程序-help,-?命令顯示幫助信息1.4 -verbose命令輸出詳細(xì)數(shù)據(jù)顯示運(yùn)行過(guò)程MiniJavaVM的運(yùn)行環(huán)境及開(kāi)發(fā)工具開(kāi)發(fā)平臺(tái):WindowsXP/2003開(kāi)發(fā)語(yǔ)言:ANSIC/C+開(kāi)發(fā)工具:VisualStudioC+/VisualS運(yùn)行平臺(tái):WindowsXP/2000/2003第二章系統(tǒng)設(shè)計(jì)2.1 唯一的虛擬機(jī)MiniJavaVM一個(gè)運(yùn)行的Java虛擬機(jī)實(shí)例的夭職就是:負(fù)責(zé)運(yùn)行一個(gè)Java程序。當(dāng)啟動(dòng)一個(gè)Java程序時(shí),一個(gè)虛擬機(jī)實(shí)例也就誕生了

19、。當(dāng)該程序關(guān)閉退出,這個(gè)虛擬機(jī)實(shí)例也就隨之消亡。如果在同一臺(tái)計(jì)算機(jī)上同時(shí)運(yùn)行三個(gè)Java程序,將得到三個(gè)Java虛擬機(jī)實(shí)例。每個(gè)Java程序?qū)嵗歼\(yùn)行于它自己的Java虛擬機(jī)實(shí)例中。錯(cuò)誤!未定義書(shū)簽。為此,需要有一種機(jī)制保證在運(yùn)行過(guò)程中只有一個(gè)Java虛擬機(jī)的實(shí)例產(chǎn)生。首先要定義表示Java虛擬機(jī)的類(lèi),然后保證這個(gè)類(lèi)有只一個(gè)實(shí)例。一種可以供選擇的方案是使用Singleton設(shè)計(jì)模式,保證Java虛擬機(jī)實(shí)例在整個(gè)程序運(yùn)行過(guò)程中只有一個(gè);另一種是可以考慮MFC(MicrosoftFundamentalClass)中唯一的全局變量theApp來(lái)表示程序運(yùn)行的實(shí)例,通過(guò)AfxGetApp()的方法來(lái)得

20、到該唯一的全局變量的指針,然后在此基礎(chǔ)上進(jìn)行操作。在這里,我們選擇MF5式定義唯一的全局變量來(lái)表示Java虛擬機(jī)的運(yùn)行實(shí)例,可以在程序進(jìn)入main()函數(shù)前完成虛擬機(jī)的初始化。通過(guò)定義一個(gè)全局函數(shù)來(lái)返回虛擬機(jī)實(shí)例的指針。2.2 MiniJavaVM的構(gòu)成要素2.2.1 虛擬機(jī)總體框架我們的MiniJavaVM的框架合理地組織了虛擬機(jī)運(yùn)行時(shí)所需的各模塊,將各模塊的輸入與輸出有效地結(jié)合在一起,使這些模塊組合在一起完成了Java虛擬機(jī)的功能。這些模塊包括:命令參數(shù)解析模塊、類(lèi)的裝載和解析模塊、內(nèi)存管理模塊、執(zhí)行引擎模塊、方法調(diào)用模塊、異常處理模塊、多線程處理模塊(未完成)。我們的MiniJavaVM

21、總的組織方式如圖2.2.1所示。輸入命令:命令參數(shù)解析模塊U:根據(jù)MiniJavaVM后的參數(shù)來(lái)設(shè)定虛擬機(jī):的運(yùn)行模式及輸出信息1類(lèi)的裝載和解析模塊:內(nèi)存管理模塊:裝載指定名稱(chēng)的java類(lèi),并采用退解析;的方式在需要時(shí)解析該類(lèi),類(lèi)的信息維:護(hù)在虛擬機(jī)的一個(gè)數(shù)據(jù)結(jié)構(gòu)中為類(lèi)的實(shí)例及靜態(tài)字段分配空間并在虛擬機(jī)內(nèi)維護(hù)實(shí)例,當(dāng)空間不足時(shí)啟動(dòng)垃圾回收機(jī)制來(lái)回收內(nèi)存當(dāng)調(diào)用一個(gè)方法時(shí)(本地方法與非本地方法)使用此模塊,包括找到指定方法全限定名的方法與處理參數(shù)壓棧及調(diào)用方法并返回的過(guò)程:當(dāng)虛擬機(jī)拋出異常且不能處理時(shí);記錄異常信息,在程序退出前輸出虛擬機(jī)圖2.2.1MiniJavaVM的模塊組織其中除命令參數(shù)解析

22、模塊外,其他模塊一起構(gòu)成了完整的MiniJavaVM虛擬機(jī),這些模塊之間協(xié)同合作,完成了虛擬機(jī)的功能。其中命令參數(shù)解析模塊負(fù)責(zé)解析命令,根據(jù)MiniJavaVM后的參數(shù)來(lái)設(shè)定虛擬機(jī)的運(yùn)行模式及輸出信息;類(lèi)的裝載和解析模塊能從class文件或是rt.jar文件中裝載指定名稱(chēng)的Java類(lèi),并采用退解析的方式在需要時(shí)解析該類(lèi),類(lèi)的信息維護(hù)在虛擬機(jī)的一個(gè)數(shù)據(jù)結(jié)構(gòu)中;內(nèi)存管理模塊負(fù)責(zé)為類(lèi)的實(shí)例及靜態(tài)字段分配空間,并在虛擬機(jī)內(nèi)維護(hù)類(lèi)的實(shí)例和靜態(tài)字段,當(dāng)虛擬機(jī)空間不足時(shí)會(huì)啟動(dòng)垃圾回收機(jī)制來(lái)回收內(nèi)存;執(zhí)行引擎模塊負(fù)責(zé)解釋執(zhí)行200多個(gè)操作碼,解釋的過(guò)程包括對(duì)棧楨、棧、PG局部變量區(qū)的修改;多線程處理模塊負(fù)責(zé)維

23、護(hù)虛擬機(jī)內(nèi)的表示線程的數(shù)據(jù)結(jié)構(gòu),在語(yǔ)言級(jí)提供多線程支持;方法調(diào)用模塊負(fù)責(zé)處理方法調(diào)用過(guò)程,對(duì)于非本地方法,包括找到調(diào)用方法的指針,新建棧楨、將方法參數(shù)設(shè)置在新棧楨的局部變量區(qū),調(diào)用方法并將返回值壓棧的過(guò)程,對(duì)于本地方法,包括找到調(diào)用方法的指針,將方法參數(shù)用匯編的方式壓棧,調(diào)用本地方法并將返回值壓棧的過(guò)程;異常處理模塊負(fù)責(zé)處理虛擬機(jī)拋出的異常,記錄異常產(chǎn)生處的異常信息,并試圖通過(guò)查找當(dāng)前方法的異常表來(lái)處理異常信息,如果能夠通過(guò)異常表找到處理異常的代碼,則修改PC的值使虛擬機(jī)處理當(dāng)前異常,否則,當(dāng)虛擬機(jī)不能處理該異常時(shí),輸出MiniJavaVM虛擬異常信息,然后終止虛擬機(jī)的運(yùn)行。通過(guò)這幾個(gè)模塊的協(xié)

24、同合作,我們的機(jī)能夠很好地模擬Java虛擬機(jī)的功能。2.2.2命令參數(shù)解析模塊命令參數(shù)解析模塊負(fù)責(zé)解析命令行,根據(jù)MiniJavaVM后的參數(shù)來(lái)設(shè)定虛擬機(jī)的運(yùn)行模式及輸出信息。該模塊的設(shè)計(jì)如圖2.2.2所示:命令參數(shù)解析模塊4命令行參數(shù)將命令行參數(shù)翻譯成虛擬機(jī)運(yùn)行時(shí)參數(shù)圖2.2.2命令行參數(shù)解析模塊命令參數(shù)解析模塊在解析完命令行參數(shù)后,通過(guò)得到虛擬機(jī)的唯一實(shí)例的指針調(diào)用設(shè)置參數(shù)的方法來(lái)設(shè)置虛擬機(jī)運(yùn)行時(shí)的參數(shù)。2.2.3類(lèi)的裝載和解析模塊類(lèi)的裝載和解析模塊負(fù)責(zé)從javaclass類(lèi),并采用退解析的方式在需要時(shí)解析該類(lèi),文件或是rt.jar文件中裝載指定名稱(chēng)的Java類(lèi)的信息維護(hù)在虛擬機(jī)的一個(gè)數(shù)據(jù)

25、結(jié)構(gòu)中。我們的MiniJavaVM類(lèi)的裝載和解析模塊設(shè)計(jì)如圖2.2.3所示:需要解析類(lèi)信息1類(lèi)的裝載和解析模塊I:類(lèi)的裝載和解析過(guò)程I圖2.2.3類(lèi)的裝載和解析模塊其中要裝載的類(lèi)文件有兩種渠道獲得,一種是直接查找相應(yīng)類(lèi)的class文件,一種是從rt.jar文件中得到類(lèi)的class文件的數(shù)據(jù),為了統(tǒng)一這兩種方式,可以先從這兩種方法中生成類(lèi)文件的字節(jié)流,再交由下一步程序處理。當(dāng)生成class文件的字節(jié)流后,通過(guò)指定的模塊讀取字節(jié)流中的信息,生成該Java類(lèi)在虛擬機(jī)中對(duì)應(yīng)的數(shù)據(jù)。這樣,類(lèi)裝載的部分算是完成。在虛擬機(jī)運(yùn)行的過(guò)程中,會(huì)需要解析類(lèi)中的常量池,將符號(hào)引用替換為直接引用。2.2.4內(nèi)存管理模塊

26、內(nèi)存管理模塊負(fù)責(zé)為類(lèi)的實(shí)例及靜態(tài)字段分配空間,并在虛擬機(jī)內(nèi)維護(hù)類(lèi)的實(shí)例和靜態(tài)字段,當(dāng)虛擬機(jī)空間不足時(shí)會(huì)啟動(dòng)垃圾回收機(jī)制來(lái)回收內(nèi)存。在Java虛擬機(jī)中,關(guān)于被裝載類(lèi)型的信息存儲(chǔ)在一個(gè)邏輯上稱(chēng)為方法區(qū)的內(nèi)存中,所有線程共享方法區(qū),因此它們對(duì)方法區(qū)數(shù)據(jù)的訪問(wèn)必須被設(shè)計(jì)為是線程安全的。方法區(qū)的大小不必是固定的,虛擬機(jī)可以根據(jù)應(yīng)用的需要?jiǎng)討B(tài)調(diào)整。同樣,方法區(qū)也不必是連續(xù)的,方法區(qū)可以在一個(gè)堆(甚至是虛擬機(jī)自己的堆)中自由分配。另外,虛擬機(jī)也可以允許用戶(hù)或者程序員指定方法區(qū)的初始大小以及最小和最大尺寸等。錯(cuò)誤!未定義書(shū)簽。方法區(qū)也可以被垃圾收集。因?yàn)樘摂M機(jī)允許用戶(hù)定義的類(lèi)裝載器來(lái)動(dòng)態(tài)擴(kuò)展Java程序,因此

27、一些類(lèi)也會(huì)成為程序不再引用”的類(lèi)。當(dāng)某個(gè)類(lèi)變?yōu)椴辉俦灰玫念?lèi)時(shí),Java虛擬機(jī)可以卸載這個(gè)類(lèi)(垃圾收集),從而使方法區(qū)占據(jù)的內(nèi)存保持最小。為了簡(jiǎn)單,我們的MiniJavaVM的方法區(qū)使用虛擬機(jī)自己的堆,不參與垃圾回收,同時(shí),類(lèi)的靜態(tài)字段及一些特殊的類(lèi)的實(shí)例(如與每個(gè)類(lèi)相關(guān)的Class類(lèi)的實(shí)例)也不參與垃圾回收。我們的MiniJavaVM內(nèi)存管理模塊設(shè)計(jì)如圖2.2.4所示::內(nèi)存管理模塊當(dāng)MiniJavaVM虛擬機(jī)請(qǐng)求一個(gè)可以被回收的內(nèi)存空間(比如普通類(lèi)的實(shí)例空間)時(shí),則通過(guò)內(nèi)存管理模塊分配可回收的內(nèi)存,所分配的內(nèi)存的實(shí)地址經(jīng)過(guò)映射后返回給虛擬機(jī),同時(shí)已分配的內(nèi)存地址記錄在一張哈希表中,供快速查

28、找所用。如果虛擬機(jī)已經(jīng)沒(méi)有可分配的空間,則運(yùn)行垃圾收集,垃圾收集完成后再分配內(nèi)存。當(dāng)虛擬機(jī)請(qǐng)求一個(gè)不可被回收的內(nèi)存空間(比如類(lèi)的靜態(tài)字段空間,表示已裝載類(lèi)的Class類(lèi)的實(shí)例等)時(shí),通過(guò)內(nèi)存管理模塊分配不可回收內(nèi)存,所分配的內(nèi)存的實(shí)地址經(jīng)過(guò)映射后返回給虛擬機(jī),同時(shí)已分配的內(nèi)存地址記錄在一張哈希表中,供快速查找所用。當(dāng)垃圾收集完成后仍沒(méi)有可分配的內(nèi)存地址可用時(shí),虛擬機(jī)退出。2.2.5執(zhí)行引擎模塊任何Java虛擬機(jī)實(shí)現(xiàn)的核心都是它的執(zhí)行引擎。在Java虛擬機(jī)規(guī)范中,執(zhí)行引擎的行為使用指令集來(lái)定義。對(duì)于每條指令,Java虛擬機(jī)規(guī)范都詳細(xì)規(guī)定了當(dāng)實(shí)現(xiàn)執(zhí)行到該指令時(shí)應(yīng)該處理什么。錯(cuò)誤!未定義書(shū)簽。執(zhí)行引

29、擎模塊負(fù)責(zé)解釋執(zhí)行Java200多個(gè)操作碼,解釋的過(guò)程包括對(duì)Java棧楨、Java棧、PG局部變量區(qū)的修改。我們的MiniJavaVM執(zhí)行引擎模塊設(shè)計(jì)如圖2.2.5所示::執(zhí)行引擎模塊字節(jié)碼流解釋完成操作碼的功能取操無(wú)操作碼判斷是否是Java操作碼結(jié)束虛擬機(jī)運(yùn)行異常圖2.2.5執(zhí)行引擎模塊在調(diào)用執(zhí)行引擎模塊時(shí),會(huì)傳入一字節(jié)碼流,執(zhí)行引擎模塊負(fù)責(zé)解釋這一字節(jié)碼流。在解釋字節(jié)碼過(guò)程中,Java虛擬機(jī)可能會(huì)裝載新的Java類(lèi),分配某個(gè)Java類(lèi)的實(shí)例,進(jìn)行數(shù)學(xué)運(yùn)算,修改當(dāng)前java棧楨、Java棧、PG局部變量區(qū)等。2.2.6方法調(diào)用模塊方法調(diào)用模塊負(fù)責(zé)處理方法調(diào)用過(guò)程,對(duì)于非本地方法,包括找到調(diào)用

30、方法的指針,新建棧楨、將方法參數(shù)設(shè)置在新棧楨的局部變量區(qū),調(diào)用方法并將返回值壓棧的過(guò)程,對(duì)于本地方法,包括找到調(diào)用方法的指針,將方法參數(shù)用匯編的方式壓棧,調(diào)用本地方法并將返回值壓棧的過(guò)程。我們的MiniJavaVM方法調(diào)用模塊的設(shè)計(jì)如圖2.2.6所示:如有異常拋出異常,調(diào)用異常處理模塊1方法調(diào)用模塊非本地方法查找該方法在虛擬機(jī)中對(duì)應(yīng)的數(shù)據(jù)結(jié)構(gòu)I本地方法Java方法調(diào)用調(diào)用方法的名稱(chēng)和描述符圖2.2.6方法調(diào)用模塊虛擬機(jī)為每一個(gè)調(diào)用的Java(非本地)方法一個(gè)新的棧幀。棧幀包括:為方法的局部變量所預(yù)留的空間,該方法的操作數(shù)棧,以及特定虛擬機(jī)實(shí)現(xiàn)需要的其他所有信息。局部變量和操作數(shù)棧的大小在編譯時(shí)

31、計(jì)算出來(lái),并放置到class文件中去,然后虛擬機(jī)就能夠了解到方法的棧幀需要多少內(nèi)存。當(dāng)虛擬機(jī)調(diào)用一個(gè)方法的時(shí)候,它為該方法創(chuàng)建恰當(dāng)大小的棧幀,再將新的棧幀壓入Java棧。處理實(shí)例方法時(shí),虛擬機(jī)從所調(diào)用方法棧幀內(nèi)的操作數(shù)棧中彈出objectref和args。虛擬機(jī)把objectref作為全局變量0放到新的棧幀中,把所有的args作為局部變量1,2,等處理。Objectref是隱式傳給所有實(shí)例方法的this指針。對(duì)于類(lèi)方法,虛擬機(jī)只從所調(diào)用的方法棧幀中的操作數(shù)棧中彈出參數(shù),并將它們放到新的棧幀中去作為局部變量0,1,2當(dāng)objectref和args(對(duì)于類(lèi)方法則只有args)被賦給新棧幀中的局部變

32、量后,虛擬機(jī)把新的棧幀作為當(dāng)前棧幀,然后將程序計(jì)數(shù)器指向新方法的第一條指令。錯(cuò)誤!未定義書(shū)簽。虛擬機(jī)使用一種與實(shí)現(xiàn)相關(guān)”的風(fēng)格調(diào)用本地方法。當(dāng)調(diào)用本地方法時(shí),虛擬機(jī)不會(huì)將一個(gè)新的棧幀壓入Java棧。當(dāng)線程進(jìn)入到本地方法的那一刻,它就將Java棧拋在身后。直到本地方法返回以后,Java棧才被重新調(diào)用。這里本虛擬機(jī)的實(shí)現(xiàn)將使用調(diào)用動(dòng)態(tài)鏈接庫(kù)中的方法來(lái)實(shí)現(xiàn)本地方法調(diào)用的過(guò)程。2.2.7 異常處理模塊異常處理模塊負(fù)責(zé)處理虛擬機(jī)拋出的異常,記錄異常產(chǎn)生處的異常信息,并試圖通過(guò)查找當(dāng)前方法的異常表來(lái)處理異常信息,如果能夠通過(guò)異常表找到處理異常的代碼,則修改PC的值使虛擬機(jī)處理當(dāng)前異常,否則,當(dāng)虛擬機(jī)不能處

33、理該異常時(shí),輸出異常信息,然后終止虛擬機(jī)的運(yùn)行。我們的MiniJavaVM異常處理模塊的設(shè)計(jì)如圖2.2.7所示:異常處理模塊圖2.2.7異常處理模塊第三章虛擬機(jī)框架的實(shí)現(xiàn)Java虛擬機(jī)的體系結(jié)構(gòu)如圖3.1所示:Class文件類(lèi)裝載器子系統(tǒng)方法區(qū)堆JavaBPC寄存器本地方法棧運(yùn)行時(shí)數(shù)據(jù)區(qū)本地方法接口本地方法庫(kù)圖3.1Java虛擬機(jī)的內(nèi)部體系結(jié)構(gòu)實(shí)現(xiàn)虛擬機(jī)框架,需要考慮以下幾點(diǎn):虛擬機(jī)的數(shù)據(jù)類(lèi)型和字長(zhǎng)如何實(shí)現(xiàn)棧結(jié)構(gòu)如何裝載和解析類(lèi)如何調(diào)用本地和非本地方法如何實(shí)現(xiàn)執(zhí)行引擎如何實(shí)現(xiàn)多線程機(jī)如何組織方法區(qū)和堆如何進(jìn)行垃圾回收虛擬機(jī)如何處理異常為了解決這些問(wèn)題,這里我們把MiniJavaVM虛擬機(jī)的實(shí)現(xiàn)

34、總體分為三部分。第一部分為主體部分,JavaVM工程。這個(gè)工程相當(dāng)于實(shí)現(xiàn)了一個(gè)Java虛擬機(jī)的所有功能,包括定義虛擬機(jī)的數(shù)據(jù)類(lèi)型和字長(zhǎng),實(shí)現(xiàn)虛擬機(jī)棧結(jié)構(gòu),組織方法區(qū)和堆,裝載和解析類(lèi),實(shí)現(xiàn)執(zhí)行引擎,調(diào)用非本地方法,實(shí)現(xiàn)多線程,處理異常等。但這個(gè)工程不負(fù)責(zé)虛擬機(jī)在執(zhí)行過(guò)程中需要調(diào)用的本地方法的實(shí)現(xiàn)。由于本地方法總是與Java虛擬機(jī)實(shí)現(xiàn)的底層平臺(tái)相關(guān)的,因此這個(gè)工程只負(fù)責(zé)處理與底層平臺(tái)實(shí)現(xiàn)不相關(guān)的部分,而將與底層平臺(tái)實(shí)現(xiàn)相關(guān)的部分交給另外一個(gè)工程JavaNativeCall工程。JavaVM工程將開(kāi)發(fā)為動(dòng)態(tài)鏈接庫(kù)的形式,有利于別的工程調(diào)用這個(gè)工程中重要的導(dǎo)出類(lèi)和導(dǎo)出方法。第二部分為本地方法實(shí)現(xiàn)部分

35、,JavaNativeCall工程。此工程負(fù)責(zé)本地方法接口(JNI)的聲明和實(shí)現(xiàn)。該工程將開(kāi)發(fā)為動(dòng)態(tài)鏈接庫(kù)的形式,有利于JavaVM工程調(diào)用該工程中的導(dǎo)出函數(shù)。第三部分為主程序,JVM工程。該工程負(fù)責(zé)解析并設(shè)置虛擬機(jī)運(yùn)行參數(shù),調(diào)用JavaVM工程的虛擬機(jī)實(shí)現(xiàn)類(lèi)來(lái)啟動(dòng)虛擬機(jī)。該工程為可執(zhí)行文件。3.1 我們將主程序與虛擬機(jī)工程分離,底層平臺(tái)實(shí)現(xiàn)相關(guān)與實(shí)現(xiàn)無(wú)關(guān)部分代碼分離,使MiniJavaVM虛擬機(jī)的實(shí)現(xiàn)更具層次感。同時(shí),也具有了更好的可擴(kuò)充性JVM工程JVM工程負(fù)責(zé)解析并設(shè)置虛擬機(jī)運(yùn)行參數(shù),調(diào)用JavaVM工程的虛擬機(jī)實(shí)現(xiàn)類(lèi)來(lái)啟動(dòng)虛擬機(jī)。JVM工程所要完成的任務(wù)可以用圖3.1.1表示:初始化虛

36、擬機(jī)參數(shù)圖3.1.1JVM工程流程JVM工程只是調(diào)用JavaVM工程中導(dǎo)出的JavaVM類(lèi),設(shè)置其參數(shù)及入口類(lèi),所有Java虛擬機(jī)的運(yùn)行工程交由JavaVM類(lèi)完成。3.2 JavaVM工程JavaVM工程實(shí)現(xiàn)了一個(gè)Java虛擬機(jī)的所有功能,包括定義虛擬機(jī)的數(shù)據(jù)類(lèi)型和字長(zhǎng),實(shí)現(xiàn)虛擬機(jī)棧結(jié)構(gòu),組織方法區(qū)和堆,裝載和解析類(lèi),實(shí)現(xiàn)執(zhí)行引擎,調(diào)用非本地方法,實(shí)現(xiàn)多線程,處理異常等。但這個(gè)工程不負(fù)責(zé)虛擬機(jī)在執(zhí)行過(guò)程中需要調(diào)用的本地方法的實(shí)現(xiàn)。由于本地方法總是與Java虛擬機(jī)實(shí)現(xiàn)的底層平臺(tái)相關(guān)的,因此這個(gè)工程只負(fù)責(zé)處理與底層平臺(tái)實(shí)現(xiàn)不相關(guān)的部分,而將與底層平臺(tái)實(shí)現(xiàn)相關(guān)的部分交給另外一個(gè)工程JavaNativ

37、eCall工程。3.2.1 Java虛擬機(jī)的數(shù)據(jù)類(lèi)型和字長(zhǎng)考量Java虛擬機(jī)是通過(guò)某些數(shù)據(jù)類(lèi)型來(lái)執(zhí)行計(jì)算的,數(shù)據(jù)類(lèi)型及其運(yùn)算都是由Java虛擬機(jī)規(guī)范嚴(yán)格定義的。數(shù)據(jù)類(lèi)型可以分為兩種:基本類(lèi)型和引用類(lèi)型?;绢?lèi)型的變量持有原始值,而引用類(lèi)型的變量持有引用值,圖3.2.1描述了Java虛擬機(jī)中的數(shù)據(jù)類(lèi)型:引用類(lèi)型基本類(lèi)型圖3.1.1Jav睫擬機(jī)中的數(shù)據(jù)類(lèi)型Java虛擬機(jī)規(guī)范定義了每一種數(shù)據(jù)類(lèi)型的取值范圍,但是沒(méi)有定義它們的位寬。存儲(chǔ)這些類(lèi)型的值所需的占位寬度,是由具體的虛擬機(jī)實(shí)現(xiàn)的設(shè)計(jì)者決定的。Java語(yǔ)言中的所有基本類(lèi)型同樣也是Java虛擬機(jī)中的基本類(lèi)型。但boolean有點(diǎn)特別,當(dāng)編譯器把Ja

38、va源碼編譯為字節(jié)碼時(shí),它會(huì)用int或byte來(lái)表示boolean。在Java虛擬機(jī)中,false是由整數(shù)零來(lái)表示的,所有非零整數(shù)都表示true。涉及boolean值的操作則會(huì)使用int。表3.2.1Java虛擬機(jī)數(shù)據(jù)類(lèi)型的取值范圍類(lèi)型范圍ByteShortIntLongCharFloatDoubleReturnAddressReference8比特,帶符號(hào),二進(jìn)制補(bǔ)碼16比特,帶符號(hào),二進(jìn)制補(bǔ)碼32比特,帶符號(hào),二進(jìn)制補(bǔ)碼64比特,帶符號(hào),二進(jìn)制補(bǔ)碼16比特,不帶符號(hào),Unicode字符32比特,IEEE754標(biāo)準(zhǔn)單精度浮點(diǎn)數(shù)64比特,IEEE754標(biāo)準(zhǔn)單精度浮點(diǎn)數(shù)問(wèn)一方法中某操作碼的地址堆

39、中對(duì)某對(duì)象的引用,或者是nullJava虛擬機(jī)中,最基本的數(shù)據(jù)單元就是字(word),它的大小是由每個(gè)虛擬機(jī)實(shí)現(xiàn)的設(shè)計(jì)者來(lái)決定的。字長(zhǎng)必須足夠大,至少是一個(gè)字單元就足以持有byte、short、int、char、float、returnAddress或者reference類(lèi)型的值,而兩個(gè)字單元就足以持有l(wèi)ong或者double類(lèi)型的值。因此,虛擬機(jī)實(shí)現(xiàn)的設(shè)計(jì)者至少得選擇32位作為字長(zhǎng),或者選擇更為高效的字長(zhǎng)大小。通常根據(jù)底層主機(jī)平臺(tái)的指針長(zhǎng)度來(lái)選擇字長(zhǎng)。Java虛擬機(jī)規(guī)范中,關(guān)于運(yùn)行時(shí)數(shù)據(jù)區(qū)的大部分內(nèi)容,都是基于“字”這個(gè)抽象概念的。比如,關(guān)于棧幀的兩個(gè)部分一一局部變量和操作數(shù)棧一一都是按照“

40、字”來(lái)定義的。這個(gè)內(nèi)容區(qū)域能夠容納任何虛擬機(jī)數(shù)據(jù)類(lèi)型的值,當(dāng)把這些值放到局部變量或者操作數(shù)棧中時(shí),它將占用一個(gè)或兩個(gè)字單元。錯(cuò)誤!未定義書(shū)簽。在我們的JavaVM工程中,對(duì)Java虛擬機(jī)的數(shù)據(jù)類(lèi)型和字長(zhǎng)的定義如下:#definenull0typedefunsignedlongword;typedefunsignedcharjava_bool;typedefunsignedshortjava_char;typedefcharjava_byte;typedefshortjava_short;typedeflongjava_int;typedef_int64java_long;typedeffloa

41、tjava_float;typedefdoublejava_double;typedefvoidjava_void;typedefwordjava_reference;定義字長(zhǎng),32位無(wú)符號(hào)long型為word定義Java數(shù)據(jù)類(lèi)型圖3.2.2JavaVM工程中數(shù)據(jù)類(lèi)型定義3.2.2 JavaVM類(lèi)JavaVM類(lèi)是JavaVM工程中最重要的一個(gè)類(lèi),這個(gè)類(lèi)定義了Java虛擬機(jī)應(yīng)該實(shí)現(xiàn)的功能,所有Java虛擬機(jī)相關(guān)的功能對(duì)應(yīng)于通過(guò)調(diào)用該類(lèi)的相應(yīng)方法來(lái)實(shí)現(xiàn)。為了定義JavaVM類(lèi),我們必須定義其他一些輔助類(lèi)。這些輔助類(lèi)包括:JavaThread類(lèi):負(fù)責(zé)管理虛擬機(jī)線程CClassFile類(lèi):負(fù)責(zé)讀取Ja

42、vaClass文件的內(nèi)容JavaClassInfo類(lèi):負(fù)責(zé)根據(jù)CClassFile類(lèi)的內(nèi)容生成該java類(lèi)的類(lèi)信息JavaArrayInfo類(lèi):負(fù)責(zé)生成某一類(lèi)型的數(shù)組信息JavaClass類(lèi):負(fù)責(zé)找出要裝載的javaclass文件,并將文件內(nèi)容作為二進(jìn)制流傳給CClassFile類(lèi)Cp_xxxxxxxx類(lèi):負(fù)責(zé)維護(hù)Class文件中常量池的內(nèi)容Attr_xxxxxxxx類(lèi):負(fù)責(zé)維護(hù)Class文件常量池中attr_info相關(guān)的內(nèi)容Memxxxxxxx類(lèi):負(fù)責(zé)虛擬機(jī)的內(nèi)存管理,包括分配內(nèi)存和進(jìn)行垃圾收集JavaVM類(lèi)的接口定義如下:/為Java虛擬機(jī)起一個(gè)新的線程,返回值為這個(gè)新線程的指針Java

43、Thread*CreateNewJavaThread();/得到當(dāng)前線程的java/lang/Thread實(shí)例引用wordGetCurrentThreadReference()const;/根據(jù)Thread的reference來(lái)判斷該Thread是否還是aliveboolIsThreadAlive(wordobjref);設(shè)置虛擬機(jī)入口的JavaClass類(lèi)boolSetExecuteClassName(constchar*szClassName);/運(yùn)行Java虛擬機(jī)boolExecute();voidPushNewStackFrame(intnMax_local);voidPushStac

44、kFrame(StackFrame*pStackFrame);voidPopStackFrame();voidPushValue(wordvalue);wordPopValue();boolIsStackEmpty();boolIsStackFrameEmpty();StackFrame*GetCurrentStackFrame();/通過(guò)class名得到該class的內(nèi)容CClassFile*GetClassFileByName(constchar*szClassName);/通過(guò)引用得到該引用對(duì)應(yīng)的Class的內(nèi)容CClassFile*GetClassFileByReference(wor

45、dref);/裝載一個(gè)指定的Java類(lèi)CClassFile*LoadClass(constchar*szClassName);/根據(jù)引用得到一個(gè)java數(shù)組的信息JavaArrayInfo*GetArrayInfoByReference(wordarrayref);/根據(jù)引用得到一個(gè)javaString類(lèi)型浦字符串值stringGetStringByStringReference(wordref);/將一個(gè)String類(lèi)型的引用與String的內(nèi)容在虛擬機(jī)內(nèi)建立關(guān)聯(lián)voidSetStringByStringReference(wordref,conststring&s);/根據(jù)clas

46、s的名稱(chēng)得到對(duì)應(yīng)的表示該class的Class類(lèi)型的實(shí)例的引用多線程相關(guān)接口虛擬機(jī)啟動(dòng)相關(guān)接口虛擬機(jī)棧相關(guān)操作接口Javal用與Class內(nèi)容相關(guān)部分接口wordGetClassReferenceByClassName(conststring&szClassName);垃圾收集相關(guān)接口分配空間對(duì)內(nèi)存空間進(jìn)行操作一對(duì)局部變量進(jìn)行操作對(duì)類(lèi)的靜態(tài)字段進(jìn)行操作3類(lèi)實(shí)例的字段進(jìn)行操作/GC開(kāi)始前先將遍歷的指針指向第一個(gè)要訪問(wèn)的元素voidBeginStackTraversal();/是否對(duì)棧的訪問(wèn)結(jié)束boolIsTraversalFinished();/返回下一個(gè)棧中的元素wordGetNext

47、StackValue();/該引用是否需要調(diào)用Finalize函數(shù)boolNeedFinalize(wordref);/調(diào)用該引用的Finalize函數(shù)voidFinalize(wordref);/對(duì)于已經(jīng)調(diào)用過(guò)Fianlize函數(shù)的引用,作標(biāo)記,/使下次不再被Finalize掉voidRemoveFromFinalized(wordref);/為一個(gè)JavaClass類(lèi)的實(shí)例分配空間,返回值為referencewordAllocateClassMemory(JavaClassInfo*pClassInfo);/為一個(gè)Java數(shù)組分配空間,返回值為referencewordAllocateAr

48、rayMemory(JavaArrayInfo*pArrayInfo);/為一個(gè)Java某個(gè)類(lèi)的靜態(tài)字段分配空間,返回值為referencewordAllocateStaticFieldMemory(JavaClassInfo*pClassInfo);/把pSrc的內(nèi)容寫(xiě)size大小的數(shù)據(jù)到pDst中voidWriteMemory(wordobjref,intoffset,constvoid*pValue,size_tsize);/讀pSrc中size大小的數(shù)據(jù)到pDst中voidReadMemory(wordobjref,intoffset,void*pValue,size_tsize);/

49、得到指定index的局部變量的值wordGetLocalVariable(intindex)const;/設(shè)置指定index的局部變量的值voidSetLocalVariable(intindex,wordvalue);/設(shè)置一個(gè)實(shí)例的某一指定非靜態(tài)字段的值boolWriteInstanceNonStaticField(wordobjref,constchar*szFieldName,void*pValue,size_tsize);/讀取一個(gè)實(shí)例的景一指定靜態(tài)字段的值boolReadInstanceNonStaticField(wordobjref,constchar*szFieldName,

50、void*pValue,size_tsize);/設(shè)置一個(gè)類(lèi)的靜態(tài)字段的值boolWriteClassStaticField(constchar*szClassName,constchar*szFieldName,void*pValue,size_tsize);/讀取一個(gè)類(lèi)的靜態(tài)字段的值一boolReadClassStaticField(constchar*szClassName,constchar*szFieldName,void*pValue,size_tsize);我們的JavaVM類(lèi)內(nèi)部組織如圖3.2.3所示:JavaVM圖3.2.3JavaVM類(lèi)內(nèi)部組織結(jié)構(gòu)其中線程部分設(shè)計(jì)如圖3.2

51、.4所示:某一棧幀某一線程棧幀棧幀圖3.2.4MiniJavaVM線程組織通過(guò)上面設(shè)計(jì),使用JavaVM類(lèi)來(lái)表示Java虛擬機(jī),使用一個(gè)唯一的JavaVM的全局變量來(lái)代表運(yùn)行中的Java虛擬機(jī);使用鏈表來(lái)存儲(chǔ)在Java虛擬機(jī)上運(yùn)行的所有線程,并保留一個(gè)指向當(dāng)前線程的指針;使用鏈表來(lái)存儲(chǔ)已經(jīng)裝載的class文件的信息,并保留一個(gè)指向入口class的指針,以找到正確的main()入口;在JavaVM類(lèi)中定義內(nèi)存管理模塊的接口,通過(guò)調(diào)用這些接口來(lái)分配并讀寫(xiě)內(nèi)存,并把類(lèi)信息同相應(yīng)的返回的引用值聯(lián)系起來(lái);在JavaVM類(lèi)中定義垃圾收集模塊的接口,通過(guò)這些接口來(lái)進(jìn)行垃圾收集。3.3 JavaNativeC

52、all工程JavaNativeCall工程為本地方法實(shí)現(xiàn)部分工程。此工程負(fù)責(zé)本地方法接口(JNI)的聲明和實(shí)現(xiàn)。該工程開(kāi)發(fā)為動(dòng)態(tài)鏈接庫(kù)的形式,有利于JavaVM工程調(diào)用該工程中的導(dǎo)出函數(shù),真正做到本地方法調(diào)用的功能。為了實(shí)現(xiàn)這個(gè)工程,這里參考了Kaffe中關(guān)于JNI實(shí)現(xiàn)部分的代碼。Kaffe是一個(gè)功能強(qiáng)大的Java虛擬機(jī),它包括Java2平臺(tái)的子集,標(biāo)準(zhǔn)JavaAPI和工具來(lái)提供Java運(yùn)行時(shí)環(huán)境。錯(cuò)誤!未定義書(shū)簽。MiniJavaVM的本地方法接口(JNI)部分主要是參考了Kaffe中對(duì)本地方法接口的定義。我們的MiniJavaVM的本地方法接口的實(shí)現(xiàn)定義了如下類(lèi)型:typedefjava_

53、referencejava_object;typedefjava_objectjava_class;typedefjava_objectjava_string;typedefjava_objectjava_array;typedefjava_arrayjava_boolArray;typedefjava_arrayjava_byteArray;typedefjava_arrayjava_charArray;typedefjava_arrayjava_shortArray;typedefjava_arrayjava_intArray;typedefjava_arrayjava_longArray

54、;typedefjava_arrayjava_floatArray;typedefjava_arrayjava_doubleArray;typedefjava_arrayjava_objectArray;JNI部分新增的Javatl型定義所有JNI函數(shù)的聲明均按照“MiniJavaVM咆名+類(lèi)名+方法名+參數(shù)列表”的格式聲明。如java.lang.System類(lèi)的本地方法registerNatives()的聲明如下:java_void_MiniJava_java_lang_System_registerNatives(JavaVM*pJVM,java_classclsref);具體調(diào)用時(shí),只要

55、在裝載該方法所在的動(dòng)態(tài)鏈接庫(kù)后再得到該方法的地址,將參數(shù)壓棧,調(diào)用這個(gè)方法,就能完成這個(gè)方法的調(diào)用,也就實(shí)現(xiàn)了Java本地方法。第四章類(lèi)的裝載和解析4.1 JavaClass文件Javaclass文件中包含了Java虛擬機(jī)所需知道的、關(guān)于類(lèi)或接口的所有信息。Javaclass文件是8位字節(jié)的二進(jìn)制流。數(shù)據(jù)項(xiàng)按順序存儲(chǔ)在class文件中,相鄰的項(xiàng)之間沒(méi)有任何間隔,這樣可以使class文件更緊湊。占據(jù)多個(gè)字節(jié)空間的項(xiàng)按照高位在前的順序分為幾個(gè)連續(xù)的字節(jié)存放。錯(cuò)誤!未定義書(shū)簽。和Java類(lèi)的可以包含多個(gè)不同的字段、方法、方法參數(shù)、局部變量等一樣,Javaclass文件也能夠包含許多不同大小的項(xiàng)。在c

56、lass文件中,可變長(zhǎng)度項(xiàng)的大小和長(zhǎng)度位于其實(shí)際數(shù)據(jù)之前。這個(gè)特性使得class文件流可以從頭到尾被順序解析,首先讀出項(xiàng)的大小,然后讀出項(xiàng)的數(shù)據(jù)。Class文件的基本類(lèi)型如下,所有存儲(chǔ)在u2,u4,u8項(xiàng)中的值,在class文件中以高位在前的形式出現(xiàn)。表4.1.1class文件基本類(lèi)型u11個(gè)字節(jié),無(wú)符號(hào)類(lèi)型u22個(gè)字節(jié),無(wú)符號(hào)類(lèi)型u44個(gè)字節(jié),無(wú)符號(hào)類(lèi)型u88個(gè)字節(jié),無(wú)符號(hào)類(lèi)型可變長(zhǎng)度的ClassFile表中的項(xiàng),如表4.1.2所示:表4.1.2ClassFile表的格式類(lèi)型名稱(chēng)數(shù)量U4Magic1U2Minor_version1U2Major_version1U2Constant_pool_count1Cp_infoConstan

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論