日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
詳細(xì)介紹JVM結(jié)構(gòu)基礎(chǔ)

JVM執(zhí)行的對(duì)象就是大家非常熟悉的class文件,我們也稱為類文件,JVM規(guī)范定義的這個(gè)編譯完成的代碼文件(雖然并非強(qiáng)制要求是實(shí)際的文件)的格式非常的詳實(shí),但是我們這里只說(shuō)一些宏觀的內(nèi)容,以后有機(jī)會(huì)再研究細(xì)節(jié)的內(nèi)容吧。JVM要求的類文件的格式是和硬件和操作系統(tǒng)無(wú)關(guān)的一種二進(jìn)制格式,它精確定義了類或者接口的表示,它甚至包含了字節(jié)順序這樣的細(xì)節(jié),而字節(jié)順序在特定平臺(tái)的目標(biāo)文件格式中一般都是固定的,不會(huì)進(jìn)行說(shuō)明。

專注于為中小企業(yè)提供網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)服務(wù),電腦端+手機(jī)端+微信端的三站合一,更高效的管理,為中小企業(yè)建陽(yáng)免費(fèi)做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動(dòng)了1000+企業(yè)的穩(wěn)健成長(zhǎng),幫助中小企業(yè)通過(guò)網(wǎng)站建設(shè)實(shí)現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

JVM所支持的數(shù)據(jù)類型和Java語(yǔ)言規(guī)范中定義的幾乎一樣,請(qǐng)注意是幾乎一樣!也就是原始類型和引用類型,他們可以被存儲(chǔ)在變量表中,也可以作為參數(shù)傳遞、被方法返回,更通常的就是成為操作的對(duì)象。為什么和Java語(yǔ)言規(guī)范中定義的不完全一樣呢?因?yàn)镴VM中有一種Java語(yǔ)言所沒(méi)有的原始類型:返回地址類型(returnAddress type)。該類型是jsr, ret以及jsr_w指令需要使用到的,它的值是JVM指令的操作碼的指針,并且它的值是不能被運(yùn)行中的程序所修改的。

另外需要提到的就是布爾類型的值,雖然在Java語(yǔ)言中它是完全獨(dú)立的值,但是在JVM中只提供了對(duì)它的有限支持,表現(xiàn)在:
沒(méi)有單獨(dú)的操作布爾類型的指令,源代碼中的布爾類型的操作在編譯以后是作為int類型的值進(jìn)行操作的。

JVM直接支持布爾數(shù)組,newarray指令可以創(chuàng)建布爾數(shù)組,而它的訪問(wèn)和修改操作卻是使用byte類型的數(shù)組的操作指令進(jìn)行的:baload,bastore。(在JDK1.0,1,1以及1.2中,布爾數(shù)組被編碼為byte數(shù)組,每個(gè)元素是8位)

JVM用1代表true,用0代表false,編譯器將源代碼中的布爾類型映射為JVM中的int類型,而且必須和JVM的要求一致。

另外JVM規(guī)范中對(duì)于浮點(diǎn)類型的數(shù)據(jù)有大段的說(shuō)明,我沒(méi)有怎么看,主要是討論JVM的浮點(diǎn)型和IEEE 754的關(guān)系的。

關(guān)于類型的另外一個(gè)需要提一下的是類型檢查。JVM期望幾乎所有的類型檢查已經(jīng)在運(yùn)行之前完成了(通常是由編譯器進(jìn)行檢查的)而不用JVM自己來(lái)檢查。原始類型的值不需要被標(biāo)記或者在運(yùn)行時(shí)被檢查以確定他們的類型,同樣他們也不用和引用類型的值進(jìn)行區(qū)分,區(qū)分工作是由JVM的指令集來(lái)完成的,JVM的指令集使用不同指令來(lái)區(qū)分它要操作的值的類型,例如iadd, ladd, fadd以及dadd是用于將兩個(gè)數(shù)字相加并產(chǎn)生數(shù)字類型結(jié)果的所有JVM指令,但是每個(gè)指令都是針對(duì)特定類型的,分別對(duì)應(yīng)int, long, float以及double。

JVM包含對(duì)對(duì)象的顯式支持。類是動(dòng)態(tài)分配的類實(shí)例或者是一個(gè)數(shù)組,JVM中的引用類型就是對(duì)一個(gè)對(duì)象的引用,引用類型的值可以想象為對(duì)象的指針,一個(gè)對(duì)象同時(shí)可能存在多個(gè)對(duì)它的引用,對(duì)象總是通過(guò)引用被操作、傳遞或者測(cè)試的。

對(duì)于引用類型,需要提及的一點(diǎn)就是關(guān)于null,它最初是沒(méi)有運(yùn)行時(shí)類型的,但是它可以被轉(zhuǎn)換為任何類型,而且對(duì)于null,JVM并沒(méi)有要求任何具體的值與之對(duì)應(yīng)。

說(shuō)完上面這些,我們就開(kāi)始進(jìn)入我學(xué)習(xí)JVM時(shí)最想了解的部分了,大家可要打起精神哦。

JVM為運(yùn)行一個(gè)程序定義了幾種數(shù)據(jù)區(qū)(Data Area),包括:pc寄存器、JVM堆棧、堆、方法區(qū)(Method Area)、運(yùn)行時(shí)常量池(Runtime Constant Pool)以及本機(jī)方法堆棧(Native Method Stacks),這些數(shù)據(jù)區(qū)根據(jù)其生存期可以分為兩種,一種就是和JVM的生存期相同(包括堆和方法區(qū)),一種和線程的生存期相同(其它的),和JVM生存期相同的數(shù)據(jù)區(qū)在JVM啟動(dòng)的時(shí)候被創(chuàng)建并在JVM退出的時(shí)候被銷毀,而和線程生存期相同的數(shù)據(jù)區(qū)是每個(gè)線程一個(gè)的,他們?cè)诰€程創(chuàng)建的時(shí)候被創(chuàng)建,在線程被銷毀的時(shí)候被銷毀。

由于JVM可以同時(shí)支持運(yùn)行多個(gè)線程,因此每個(gè)線程必然需要各自的PC(program counter)寄存器,無(wú)論從什么角度講,每個(gè)JVM線程只能在一個(gè)時(shí)間只能執(zhí)行一個(gè)方法,該方法也就是線程的當(dāng)前方法,如果該方法不是本機(jī)方法,那么PC寄存器保存的就是當(dāng)前指令(JVM的指令)的地址,如果是當(dāng)前方法是本機(jī)方法,PC寄存器的值就沒(méi)有被定義。JVM的PC寄存器的大小足夠大,可以容納一個(gè)returnAddress類型或者特定平臺(tái)的本機(jī)指針。

每個(gè)JVM線程還擁有一個(gè)私有的JVM堆棧,它存儲(chǔ)幀(下一篇文章會(huì)講到)。JVM堆棧和像C這樣的傳統(tǒng)編程語(yǔ)言中的堆棧是類似的,它保存局部變量和部分結(jié)果,并且在方法調(diào)用和返回中也擔(dān)任一些職責(zé)。因?yàn)槌藢?duì)幀的壓入和彈出操作外,對(duì)JVM堆棧不能直接進(jìn)行操作,因此幀可能是在堆上分配的。如果一個(gè)線程中計(jì)算所需的JVM堆棧大于允許的大小,JVM會(huì)拋出StackOverflowError錯(cuò)誤,如果JVM堆棧是可以動(dòng)態(tài)伸縮的,如果需要擴(kuò)展,但是又沒(méi)有足夠的內(nèi)存可用或者沒(méi)有足夠的內(nèi)存為一個(gè)新線程創(chuàng)建JVM堆棧,JVM會(huì)拋出OutOfMemoryError錯(cuò)誤。

JVM只有一個(gè)為所有線程所共享的堆,所有的類實(shí)例和數(shù)組都是在堆中創(chuàng)建的。堆所存儲(chǔ)的對(duì)象被一個(gè)自動(dòng)存儲(chǔ)管理系統(tǒng)回收(也就是我們所熟知的垃圾收集器(gc))。對(duì)象不能被顯式的釋放,JVM假設(shè)沒(méi)有特定類型的自動(dòng)存儲(chǔ)管理系統(tǒng),存儲(chǔ)管理技術(shù)可以根據(jù)實(shí)現(xiàn)者的系統(tǒng)需求進(jìn)行選擇。如果計(jì)算所需的內(nèi)存堆大于自動(dòng)存儲(chǔ)管理系統(tǒng)可以使用的大小,JVM會(huì)拋出OutOfMemoryError錯(cuò)誤。

JVM只有一個(gè)為所有的線程所共享的方法區(qū),方法區(qū)類似傳統(tǒng)語(yǔ)言的已編譯代碼的存儲(chǔ)區(qū)或者UNIX進(jìn)程的“文本”段。它存儲(chǔ)類結(jié)構(gòu),例如運(yùn)行時(shí)常量池,成員和方法數(shù)據(jù)以及方法、構(gòu)造方法的代碼(包括用于類和實(shí)例的初始化以及接口類型初始化的特定方法(這些特定方法以后會(huì)講到))。雖然從邏輯上講方法區(qū)是堆的一部分,但是JVM的簡(jiǎn)單實(shí)現(xiàn)可以選擇不對(duì)方法區(qū)進(jìn)行垃圾收集或者壓縮(以筆者的理解就是類不能進(jìn)行卸載)。***版本(第二版)的JVM規(guī)范沒(méi)有要求方法區(qū)的位置或者管理已編譯代碼的策略。如果方法區(qū)的內(nèi)存不能滿足一個(gè)分配請(qǐng)求,JVM會(huì)拋出OutOfMemoryError。

運(yùn)行時(shí)常量池是類文件中的常量池表的運(yùn)行時(shí)表示,它包含幾種常量,范圍從編譯時(shí)就已知的數(shù)字常量到運(yùn)行時(shí)必須進(jìn)行解析的方法和成員引用。運(yùn)行時(shí)常量池扮演的功能類似于傳統(tǒng)編程語(yǔ)言中的符號(hào)表(symbol table),但是它所包含的數(shù)據(jù)比典型的符號(hào)表更多。

每個(gè)運(yùn)行時(shí)常量池時(shí)從JVM的方法區(qū)中分配的,對(duì)于特定方法或者接口的運(yùn)行時(shí)常量池是JVM在創(chuàng)建類或者接口的時(shí)候創(chuàng)建的。
當(dāng)創(chuàng)建一個(gè)類或者接口時(shí),如果創(chuàng)建運(yùn)行時(shí)常量池需要的內(nèi)存比方法區(qū)中的可用內(nèi)容更多的內(nèi)存,JVM會(huì)拋出OutOfMemoryError。

關(guān)于常量池創(chuàng)建的更多內(nèi)容以后可能會(huì)更詳細(xì)的講解。

JVM的實(shí)現(xiàn)可能使用傳統(tǒng)的堆棧(更通常的講就是C棧)以支持本機(jī)方法(不是使用JAVA語(yǔ)言編寫的方法),本機(jī)方法堆棧也可以用于在像C語(yǔ)言這樣的語(yǔ)言中為JVM指令集實(shí)現(xiàn)解析器,對(duì)于不能加載本機(jī)方法以及自身不依賴傳統(tǒng)堆棧的JVM實(shí)現(xiàn)而言,它可以不提供本機(jī)方法堆棧,如果提供,本機(jī)方法堆棧通常在線程創(chuàng)建的時(shí)候?yàn)槊總€(gè)線程分配(以筆者的理解應(yīng)該是需要使用本機(jī)方法的線程)。如果線程計(jì)算所需的內(nèi)存比本機(jī)方法堆棧所允許的大,JVM會(huì)拋出StackOverflowError錯(cuò)誤,如果本機(jī)方法堆??梢詣?dòng)態(tài)伸縮,而當(dāng)需要擴(kuò)展的時(shí)候又沒(méi)有足夠的內(nèi)存時(shí),或者沒(méi)有足夠的內(nèi)容用于創(chuàng)建一個(gè)本機(jī)方法堆棧,JVM會(huì)拋出OutOfMemoryError。

對(duì)于上面的這些數(shù)據(jù)區(qū),JVM規(guī)范允許它們的大小是固定尺寸的,也可以是根據(jù)計(jì)算的需要?jiǎng)討B(tài)伸縮的,如果是固定尺寸的,其尺寸可以在創(chuàng)建時(shí)自主選擇。JVM的實(shí)現(xiàn)可以給程序員或者用戶提供控制JVM堆棧的初始大小的方法,同樣,在動(dòng)態(tài)伸縮的情況下可以控制***大小和最小大小,并且它們所使用的內(nèi)存空間可以不是連續(xù)的。


當(dāng)前標(biāo)題:詳細(xì)介紹JVM結(jié)構(gòu)基礎(chǔ)
文章URL:http://www.5511xx.com/article/dpicged.html