圖一 Java虛擬機(jī)的內(nèi)部體系結(jié)構(gòu)
每個Java虛擬機(jī)實例都有一個方法區(qū)以及一個堆,它們是由該虛擬機(jī)實例中所有線程共享的。
當(dāng)虛擬機(jī)裝載一個class文件時,它會從這個class文件包含的二進(jìn)制數(shù)據(jù)中解析類型信息,然后把這些類型信息放到方法區(qū)中;
當(dāng)程序運(yùn)行時,虛擬機(jī)會把所有該程序在運(yùn)行時創(chuàng)建的對象都放到堆中;
當(dāng)每一個新線程被創(chuàng)建時,它都將得到它自己的PC寄存器(程序計數(shù)器)以及一個Java棧,如果線程正在執(zhí)行的是一個java方法(非本地方法),那么PC寄存器的值將總是指示下一條將被執(zhí)行的指令,而它的Java棧則總是存儲該線程中java方法調(diào)用的狀態(tài)—包括它的局部變量,被調(diào)用時傳進(jìn)來的參數(shù),它的返回值,以及運(yùn)算的中間結(jié)果等等。而本地方法調(diào)用的狀態(tài),則是以某種依賴與具體實現(xiàn)的方式存儲在本地方法棧中,也可能是在寄存器或者其他某些與特定實現(xiàn)相關(guān)的內(nèi)存中。
Java棧由許多棧幀(stack frme)或者說幀(frame)組成,一個棧幀包含一個方法調(diào)用。當(dāng)線程調(diào)用一個Java方法時,虛擬機(jī)壓入一個新的棧幀到該線程的java棧中,當(dāng)該方法返回時,這個棧幀被從Java棧中彈出并拋棄。
Java虛擬機(jī)沒有寄存器,其指令集使用Java棧來存儲中間數(shù)據(jù)。
數(shù)據(jù)類型
Java虛擬機(jī)是通過某些數(shù)據(jù)類型來執(zhí)行計算的,數(shù)據(jù)類型及其運(yùn)算都是由java虛擬機(jī)規(guī)范嚴(yán)格定義的。數(shù)據(jù)類型可以分為兩種:基本類型和引用類型。基本類型的變量持有原始值,而引用類型的變量持有引用值。術(shù)語“引用值”指的是對某個對象的引用,而不是該對象本身,與此相對,原始值則是真正的原始數(shù)據(jù)。Java語言中的所有基本類型同樣也都是java虛擬機(jī)中的基本類型,但是boolean有點(diǎn)特別,雖然虛擬機(jī)也把boolean看做基本類型,但是指令集對boolean只有很有限的支持。當(dāng)編譯器把java源碼編譯成字節(jié)碼時,它會用int或byte來表示boolean。設(shè)計boolean值的操作會使用int,boolean數(shù)組是當(dāng)作byte數(shù)組來訪問的。但是在“堆”區(qū)中,它也可以被表示為位域。 類型 范圍 byte 8bit,帶符號,二進(jìn)制補(bǔ)碼,[-2∧7,2∧7-1] short 16bit,帶符號,二進(jìn)制補(bǔ)碼,[-2∧15,2∧15-1] int 32bit,帶符號,二進(jìn)制補(bǔ)碼,[-2∧31,2∧31-1] long 64bit,帶符號,二進(jìn)制補(bǔ)碼,[-2∧63,2∧63-1] char 16bit,不帶符號,Unicode字符,[0,2∧16-1] float 32bit,IEEE 754標(biāo)準(zhǔn)單精度浮點(diǎn)數(shù) double 64bit,IEEE 754標(biāo)準(zhǔn)雙進(jìn)度浮點(diǎn)數(shù) returnAddress 同一方法中某操作碼的地址 reference 堆中對某對象的引用,或者是null
Java虛擬機(jī)中,最基本的數(shù)據(jù)單元就是字(word),它的大小是由每個虛擬機(jī)實現(xiàn)的設(shè)計者來決定的。字長必須足夠大,至少是一個字單元就足以持有byte、short、int、char、float、returnAddress、reference類型的值,而兩個字單元就足以持有long或者double類型的值。因此,虛擬機(jī)實現(xiàn)的設(shè)計者至少得選擇32位作為字長。
方法區(qū)
由于所有線程都共享方法區(qū),因此它們對方法區(qū)數(shù)據(jù)的訪問必須被設(shè)計為線程安全的。
類型信息 對每個裝載的類型,虛擬機(jī)都會在方法區(qū)中存儲以下類型信息:
l 這個類型的全限定名
l 這個類型的直接超類的全限定名
l 這個類型是類類型還是接口類型
l 這個類型的訪問修飾符
l 任何直接超接口的全限定名的有序列表
除這些基本信息外,還需要如下信息:
l 該類型的常量池
l 字段信息
l 方法信息
l 除了常量以外的所有類變量
l 一個到類ClassLoader的引用
一個到Class類的引用