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

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

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
了解JVM的結(jié)構(gòu),好在面試時(shí)吹牛

了解JVM的結(jié)構(gòu),好在面試時(shí)吹牛

作者:李新杰 2019-12-23 15:17:21
云計(jì)算
虛擬化 在一個(gè)線(xiàn)程執(zhí)行的任何時(shí)刻,都只會(huì)有一個(gè)幀是處于激活的。這個(gè)幀被稱(chēng)為當(dāng)前幀,與之對(duì)應(yīng)的方法被稱(chēng)為當(dāng)前方法,方法所在的類(lèi)被稱(chēng)為當(dāng)前類(lèi),此時(shí)用到的本地變量數(shù)組和操作數(shù)棧也都是當(dāng)前幀的。

創(chuàng)新互聯(lián)公司從2013年創(chuàng)立,先為平魯?shù)确?wù)建站,平魯?shù)鹊仄髽I(yè),進(jìn)行企業(yè)商務(wù)咨詢(xún)服務(wù)。為平魯企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。

jvm包括兩種數(shù)據(jù)類(lèi)型,基本類(lèi)型和引用類(lèi)型。

基本類(lèi)型包括,數(shù)值類(lèi)型,boolean類(lèi)型,和returnAddress類(lèi)型。

數(shù)值類(lèi)型包括,整型,浮點(diǎn)型,和char類(lèi)型。

boolean類(lèi)型同樣只有true和false。

returnAddress類(lèi)型是一個(gè)指針,指向jvm指令的操作碼,在Java中沒(méi)有與之對(duì)應(yīng)的類(lèi)型。

boolean類(lèi)型的操作會(huì)被轉(zhuǎn)化為int類(lèi)型的操作進(jìn)行,boolean數(shù)組會(huì)當(dāng)成byte數(shù)組去操作。1表示true,0表示false。

引用類(lèi)型包括三種,類(lèi)類(lèi)型,數(shù)組類(lèi)型,和接口類(lèi)型。

它們的值是動(dòng)態(tài)創(chuàng)建的類(lèi)實(shí)例,數(shù)組,或?qū)崿F(xiàn)接口的類(lèi)實(shí)例。

數(shù)組有component類(lèi)型和element類(lèi)型,component類(lèi)型就是數(shù)組去掉最外層維度后剩下的類(lèi)型,可能還是一個(gè)數(shù)組類(lèi)型(對(duì)于多維數(shù)組)。

element類(lèi)型就是數(shù)組里面存儲(chǔ)的最小數(shù)據(jù)的類(lèi)型,它必須是一個(gè)基本類(lèi)型,類(lèi)類(lèi)型,或接口類(lèi)型。

對(duì)于一維數(shù)組的話(huà),component類(lèi)型和element類(lèi)型是相同的。

引用類(lèi)型還有一個(gè)特殊值,就是null,表示沒(méi)有引用任何對(duì)象。

運(yùn)行時(shí)公有數(shù)據(jù)區(qū)

jvm有一個(gè)堆,在所有jvm線(xiàn)程間共享,堆是一個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)域,所有為類(lèi)實(shí)例和數(shù)組分配的內(nèi)存都來(lái)自于它。

堆在jvm啟動(dòng)時(shí)創(chuàng)建,堆中對(duì)象不用顯式釋放,gc會(huì)幫我們釋放并回收內(nèi)存。

方法區(qū)

jvm有一個(gè)方法區(qū),在所有jvm線(xiàn)程間共享,它存儲(chǔ)每一個(gè)類(lèi)的結(jié)構(gòu)。

像運(yùn)行時(shí)常量池,字段和方法數(shù)據(jù),方法和構(gòu)造函數(shù)的代碼,還有特殊的方法用于類(lèi)和實(shí)例的初始化,以及接口的初始化。

方法區(qū)在jvm啟動(dòng)時(shí)創(chuàng)建,雖然方法區(qū)在邏輯上是堆的一部分。

但簡(jiǎn)單實(shí)現(xiàn)時(shí)可以選擇不進(jìn)行g(shù)c和壓縮,本規(guī)范沒(méi)有強(qiáng)制要求方法區(qū)的位置,也沒(méi)有要求管理已編譯代碼的策略。

運(yùn)行時(shí)常量池

運(yùn)行時(shí)常量池就是類(lèi)或接口的字節(jié)碼文件里的常量池的運(yùn)行時(shí)表示形式,它包含幾種常量。

如在編譯時(shí)就已經(jīng)知道的數(shù)字字面量值,和必須在運(yùn)行時(shí)解析的方法和字段的引用,運(yùn)行時(shí)常量池的功能類(lèi)似于傳統(tǒng)語(yǔ)言的符號(hào)表,不過(guò)它包含的數(shù)據(jù)會(huì)更加寬泛。

運(yùn)行時(shí)常量池分配在jvm的方法區(qū),類(lèi)或接口的運(yùn)行時(shí)常量池在類(lèi)或接口被jvm創(chuàng)建時(shí)才會(huì)構(gòu)建。

運(yùn)行時(shí)私有數(shù)據(jù)區(qū)

pc寄存器

jvm支持一次運(yùn)行多個(gè)線(xiàn)程,每個(gè)線(xiàn)程都有自己的pc寄存器,任何時(shí)候一個(gè)線(xiàn)程只能運(yùn)行一個(gè)方法的代碼。

如果方法不是native的,pc寄存器包含當(dāng)前正在被執(zhí)行的jvm指令地址,如果方法是native的,pc寄存器的值是未定義的。

jvm棧

每一個(gè)jvm線(xiàn)程都有一個(gè)私有的jvm棧,隨著線(xiàn)程的創(chuàng)建而創(chuàng)建,棧中存儲(chǔ)的是幀。

jvm棧和傳統(tǒng)語(yǔ)言如C的棧相似,保存局部變量和部分計(jì)算結(jié)果,參與方法的調(diào)用和返回。jvm棧主要用于幀的出棧和入棧,除此之外沒(méi)有其它操作,

幀可能是在堆上分配的,所以jvm棧使用的內(nèi)存不必是連續(xù)的。

native方法棧

native方法不是用Java語(yǔ)言寫(xiě)的,為了支持它需要使用傳統(tǒng)棧,如C語(yǔ)言棧。不過(guò)jvm不能加載native方法,所以也不需要提供native方法需要的棧。

每次當(dāng)一個(gè)方法被調(diào)用時(shí)一個(gè)新的幀會(huì)被創(chuàng)建。當(dāng)方法調(diào)用完成時(shí),與之對(duì)應(yīng)的幀會(huì)被銷(xiāo)毀,無(wú)論是正常完成還是拋異常結(jié)束。

所以幀是方法調(diào)用的具體體現(xiàn)形式,或稱(chēng)方法調(diào)用是以幀的形式進(jìn)行的。幀用來(lái)存儲(chǔ)數(shù)據(jù)和部分計(jì)算結(jié)果,和執(zhí)行動(dòng)態(tài)鏈接,方法返回值,分發(fā)異常。

幀分配在創(chuàng)建幀的線(xiàn)程的jvm棧上,每一個(gè)幀都有自己的本地變量數(shù)組,自己的操作數(shù)據(jù)棧,和一個(gè)對(duì)當(dāng)前方法所在類(lèi)的運(yùn)行時(shí)常量池的引用。

本地變量數(shù)組和操作數(shù)棧的大小在編譯時(shí)就確定了,它們隨著和幀關(guān)聯(lián)的方法編譯后的代碼一起被提供,因此幀這種數(shù)據(jù)結(jié)構(gòu)的大小只依賴(lài)于jvm的實(shí)現(xiàn),這些結(jié)構(gòu)所需的內(nèi)存可以在方法調(diào)用時(shí)同時(shí)被分配。

在一個(gè)線(xiàn)程執(zhí)行的任何時(shí)刻,都只會(huì)有一個(gè)幀是處于激活的。這個(gè)幀被稱(chēng)為當(dāng)前幀,與之對(duì)應(yīng)的方法被稱(chēng)為當(dāng)前方法,方法所在的類(lèi)被稱(chēng)為當(dāng)前類(lèi),此時(shí)用到的本地變量數(shù)組和操作數(shù)棧也都是當(dāng)前幀的。

一個(gè)幀將不在繼續(xù)是當(dāng)前幀,如果它的方法調(diào)用了另一個(gè)方法,或者它的方法結(jié)束了。

當(dāng)一個(gè)方法被調(diào)用,一個(gè)新的幀被創(chuàng)建,當(dāng)執(zhí)行控制由原來(lái)的方法傳遞到新的方法時(shí),這個(gè)新的幀變?yōu)楫?dāng)前幀。

當(dāng)方法返回時(shí),當(dāng)前幀把方法執(zhí)行的結(jié)果傳回到上一幀,當(dāng)上一幀被激活的同時(shí)當(dāng)前幀會(huì)被丟棄。

本地變量數(shù)組

每一幀都包含一個(gè)變量數(shù)組,就是都熟知的本地變量存儲(chǔ)的地方。這個(gè)本地變量數(shù)組的長(zhǎng)度在編譯時(shí)確定,隨著編譯后的方法代碼一起提供。

通常一個(gè)本地變量(的位置)能夠存儲(chǔ)一個(gè)類(lèi)型的值,但是long和double類(lèi)型卻需要兩個(gè)本地變量(的位置)才能存一個(gè)值。

本地變量按索引尋址,第一個(gè)本地變量的索引是0。long和double需要消耗兩個(gè)連續(xù)的索引,但卻是按照較小的這個(gè)索引尋址的。不能按照較大的那個(gè)索引去讀數(shù)據(jù),但是可以寫(xiě)入,當(dāng)然這樣將使本地變量?jī)?nèi)容錯(cuò)亂。

在方法被調(diào)用時(shí),jvm使用本地變量來(lái)接收傳遞進(jìn)來(lái)的參數(shù)值。在類(lèi)(靜態(tài))方法調(diào)用時(shí),所有參數(shù)被傳入從索引0開(kāi)始的連貫的本地變量數(shù)組里。

在實(shí)例(非靜態(tài))方法調(diào)用時(shí),索引0處總是傳入正在其上執(zhí)行方法調(diào)用的那個(gè)對(duì)象的引用,(就是Java中的this了),所有參數(shù)被傳入從1開(kāi)始的連貫的本地變量數(shù)組里。

操作數(shù)棧

每個(gè)幀包含一個(gè)后進(jìn)先出的棧,用于存儲(chǔ)正在執(zhí)行的jvm指令的操作數(shù),就是都熟知的操作數(shù)棧,這個(gè)棧的最大深度在編譯時(shí)就已確定,隨著編譯后的方法代碼一起提供。

當(dāng)幀被創(chuàng)建時(shí),操作數(shù)棧是空的,jvm提供一些指令用于加載常量值,本地變量值,字段值到操作數(shù)棧上,另一些jvm指令采用操作數(shù)棧上的操作數(shù)進(jìn)行操作,并把結(jié)果放回到操作數(shù)棧上。

操作數(shù)棧也用于準(zhǔn)備將要傳遞給方法調(diào)用的參數(shù)和接收方法調(diào)用返回的結(jié)果。

long和double類(lèi)型的值占用兩個(gè)單位的棧深度,其它類(lèi)型的值占用一個(gè)單位的棧深度。

動(dòng)態(tài)鏈接

每一個(gè)幀都包含了對(duì)當(dāng)前方法所屬類(lèi)型的運(yùn)行時(shí)常量池的引用。目的是為了支持方法代碼的動(dòng)態(tài)鏈接。class文件中描述一個(gè)方法引用被調(diào)用的方法和被訪問(wèn)的變量的代碼,是采用符號(hào)引用的形式實(shí)現(xiàn)的。

符號(hào)引用的形式可以粗略的認(rèn)為是字符串的形式,就是用字符串標(biāo)明需要調(diào)用哪個(gè)類(lèi)的哪個(gè)方法或訪問(wèn)哪個(gè)字段或變量。就像符號(hào)引用這個(gè)名字一樣,這些僅僅是符號(hào),是拿不到具體值的,所以必須要進(jìn)行轉(zhuǎn)換。

動(dòng)態(tài)鏈接就是把這些符號(hào)方法引用轉(zhuǎn)換為具體的方法引用,在必要時(shí)加載類(lèi)來(lái)解析尚未明確的符號(hào),把符號(hào)變量的訪問(wèn)轉(zhuǎn)換為這些變量運(yùn)行時(shí)所在存儲(chǔ)結(jié)構(gòu)的適合的偏移量(索引)。這樣的方式又稱(chēng)為后期綁定。

方法調(diào)用

一個(gè)方法調(diào)用正常完成(即沒(méi)有拋異常)時(shí),會(huì)根據(jù)所返回的值的類(lèi)型執(zhí)行一個(gè)適合的return指令,當(dāng)前幀會(huì)去恢復(fù)調(diào)用者的狀態(tài),包括它的本地變量和操作數(shù)棧,使調(diào)用者的程序計(jì)數(shù)器適合的遞增來(lái)跳過(guò)剛剛的那個(gè)方法調(diào)用指令。

返回值會(huì)被放到調(diào)用者幀的操作數(shù)棧上,然后繼續(xù)執(zhí)行調(diào)用者方法的幀。

一個(gè)方法在調(diào)用時(shí)拋出了異常,且這個(gè)異常沒(méi)有在這個(gè)方法內(nèi)被捕獲處理,將會(huì)導(dǎo)致這個(gè)方法調(diào)用的突然結(jié)束,這種情況下永遠(yuǎn)不會(huì)向方法的調(diào)用者返回一個(gè)值。

特殊方法

站在jvm的級(jí)別,每一個(gè)用Java寫(xiě)的構(gòu)造函數(shù)都以一個(gè)實(shí)例初始化方法出現(xiàn),且都是特殊的名字,就是 ,這個(gè)名字是編譯器提供的。

實(shí)例初始化方法只能在jvm內(nèi)部使用invokespecial這個(gè)指令調(diào)用,且只能在尚未初始化的類(lèi)實(shí)例上調(diào)用。

一個(gè)類(lèi)或接口最多可以有一個(gè)類(lèi)或接口初始化方法,通過(guò)調(diào)用這個(gè)方法被初始化。類(lèi)或接口的初始化方法也有特殊的名字,就是 ,該方法沒(méi)有參數(shù),且返回值是void。

方法名稱(chēng)也是由編譯器提供的,從Java7開(kāi)始,在字節(jié)碼中這個(gè)方法必須被標(biāo)記為靜態(tài)的才行。

這個(gè)初始化方法是被jvm隱式調(diào)用的,它們絕對(duì)不會(huì)直接被用任何jvm指令調(diào)用,僅作為類(lèi)初始化進(jìn)程的一部分被間接的調(diào)用。

Java類(lèi)庫(kù)

jvm必須為Java類(lèi)庫(kù)的實(shí)現(xiàn)提供足夠的支持。一些類(lèi)庫(kù)中的類(lèi)如果沒(méi)有jvm協(xié)助是無(wú)法實(shí)現(xiàn)的。

反射,就是在運(yùn)行時(shí)獲取某個(gè)類(lèi)的類(lèi)型相關(guān)信息,如它的字段信息,方法信息,構(gòu)造函數(shù)信息,父類(lèi)信息,實(shí)現(xiàn)的接口信息。

這些信息都必須是把一個(gè)類(lèi)加載完之后才可以知道的,只有jvm才可以加載類(lèi)。如java.lang.reflect這個(gè)包下的類(lèi)和Class這個(gè)類(lèi)。

在Java中加載一個(gè)類(lèi)或接口用類(lèi)加載器,即ClassLoader,背后還是委托給jvm來(lái)實(shí)現(xiàn)的。

鏈接和初始化一個(gè)類(lèi)或接口。

安全,如java.security包下的類(lèi),還有其它類(lèi)像SecurityManager。

多線(xiàn)程,如線(xiàn)程這個(gè)類(lèi)Thread。

弱引用,像java.lang.ref包下的類(lèi)。

公有設(shè)計(jì),私有實(shí)現(xiàn)

以上內(nèi)容只是jvm的一個(gè)“相對(duì)寬泛”的規(guī)范,它并不是實(shí)現(xiàn)方案,也不是實(shí)現(xiàn)細(xì)節(jié)。

實(shí)現(xiàn)者可以根據(jù)自身的需要來(lái)實(shí)現(xiàn)jvm,如運(yùn)行在后端服務(wù)器上的jvm和運(yùn)行在移動(dòng)設(shè)備上的jvm肯定側(cè)重點(diǎn)有所不同。

從事Java的人都知道,事實(shí)上jvm是有較多的實(shí)現(xiàn)版本。

由于jvm是處在Java語(yǔ)言和操作系統(tǒng)之間的,所以它要向上提供對(duì)Java的支持,向下與操作系統(tǒng)良好交互。

寫(xiě)在最后

高級(jí)語(yǔ)言(Java,C#)中的很多操作如文件操作,網(wǎng)絡(luò)操作,內(nèi)存操作,線(xiàn)程操作,I/O操作等,都不是高級(jí)語(yǔ)言自身能夠?qū)崿F(xiàn)的。

也不是它們的虛擬機(jī)(JVM,CLR)能夠?qū)崿F(xiàn)的,實(shí)際最終是由操作系統(tǒng)實(shí)現(xiàn)的,因?yàn)檫@些都是系統(tǒng)資源,只有操作系統(tǒng)才有權(quán)限訪問(wèn)。

如果你用Java或C#代碼創(chuàng)建了一個(gè)文件,千萬(wàn)不要以為是Java或C#創(chuàng)建了這個(gè)文件,它們只是層層向下調(diào)用了操作系統(tǒng)的API,然后到文件系統(tǒng)API,最后可能到磁盤(pán)驅(qū)動(dòng)程序。

由此可以看出,要想設(shè)計(jì)一門(mén)語(yǔ)言,不單單是關(guān)鍵字、語(yǔ)法、編譯器,類(lèi)庫(kù),虛擬機(jī)這些,還要深度了解操作系統(tǒng),甚至是硬件,如CPU架構(gòu)和CPU指令集等。

所以,和語(yǔ)言相關(guān)的事情,每一項(xiàng)都是異常的繁瑣復(fù)雜,都需要投入大量的人力、財(cái)力、時(shí)間去研究,最后即使研究成功了,可能沒(méi)有生態(tài),沒(méi)人使用,自然也無(wú)法賺錢(qián)。

因此,國(guó)人現(xiàn)在還沒(méi)有一門(mén)屬于自己的真正語(yǔ)言。


文章名稱(chēng):了解JVM的結(jié)構(gòu),好在面試時(shí)吹牛
文章鏈接:http://m.5511xx.com/article/copjdcg.html