JRE,Java運(yùn)行環(huán)境(Java Runtime Environment)是一個(gè)軟件,JRE可以讓計(jì)算機(jī)系統(tǒng)運(yùn)行Java應(yīng)用程序(Java Applica" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢(xún) 在線咨詢(xún)
15158846557 在線咨詢(xún)
所在位置: 首頁(yè) > 營(yíng)銷(xiāo)資訊 > 網(wǎng)站運(yùn)營(yíng) > 深入理解Java虛擬機(jī)

深入理解Java虛擬機(jī)

時(shí)間:2023-06-29 08:21:01 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)

時(shí)間:2023-06-29 08:21:01 來(lái)源:網(wǎng)站運(yùn)營(yíng)

深入理解Java虛擬機(jī):

一、JDK、JRE、JVM的關(guān)系

JDK(Java Development Kit) 是 Java 語(yǔ)言的軟件開(kāi)發(fā)工具包(SDK)。

JRE,Java運(yùn)行環(huán)境(Java Runtime Environment)是一個(gè)軟件,JRE可以讓計(jì)算機(jī)系統(tǒng)運(yùn)行Java應(yīng)用程序(Java Application)。JRE的內(nèi)部有一個(gè)Java虛擬機(jī)(Java Virtual Machine,JVM)以及一些標(biāo)準(zhǔn)的類(lèi)別函數(shù)庫(kù)(Class Library)。

JVM是Java Virtual Machine(Java虛擬機(jī))的縮寫(xiě),JVM是一種用于計(jì)算設(shè)備的規(guī)范,它是一個(gè)虛構(gòu)出來(lái)的計(jì)算機(jī),是通過(guò)在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來(lái)實(shí)現(xiàn)的。

二、JVM的基本結(jié)構(gòu)

JVM的基本結(jié)構(gòu)包含:類(lèi)加載子系統(tǒng)、運(yùn)行時(shí)數(shù)據(jù)區(qū)、執(zhí)行引擎、本地庫(kù)接口。

三、運(yùn)行時(shí)數(shù)據(jù)區(qū)域

Java虛擬機(jī)在執(zhí)行Java程序的過(guò)程中會(huì)把它所管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū)域。根據(jù)《Java虛擬機(jī)規(guī)范》的規(guī)定,Java虛擬機(jī)所管理的內(nèi)存將會(huì)包括以下幾個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)域。(數(shù)據(jù)區(qū)是真正用于存儲(chǔ)用戶(hù)數(shù)據(jù)的區(qū)域。)

程序計(jì)數(shù)器(Program Counter Register)是一塊較小的內(nèi)存空間,它可以看作是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。字節(jié)碼解釋器工作時(shí)就是通過(guò)改變這個(gè)計(jì)數(shù)器的值來(lái)選取下一條需要執(zhí)行的字節(jié)碼指令,為了線程切換后能恢復(fù)到正確的執(zhí)行位置,每條線程都需要有一個(gè)獨(dú)立的程序計(jì)數(shù)器,各條線程 之間計(jì)數(shù)器互不影響,獨(dú)立存儲(chǔ),我們稱(chēng)這類(lèi)內(nèi)存區(qū)域?yàn)椤熬€程私有”的內(nèi)存。

虛擬機(jī)棧(Java Virtual Machine Stack)也是線程私有的,它的生命周期 與線程相同。虛擬機(jī)棧描述的是Java方法執(zhí)行的線程內(nèi)存模型:每個(gè)方法被執(zhí)行的時(shí)候,Java虛擬機(jī)都會(huì)同步創(chuàng)建一個(gè)棧幀(Stack Frame)用于存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)連接、方法出口等信息。每一個(gè)方法被調(diào)用直至執(zhí)行完畢的過(guò)程,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中從入棧到出棧的過(guò)程。

局部變量表存放了編譯期可知的各種Java虛擬機(jī)基本數(shù)據(jù)類(lèi)型(boolean、byte、char、short、int、 float、long、double)、對(duì)象引用(reference類(lèi)型,它并不等同于對(duì)象本身,可能是一個(gè)指向?qū)ο笃鹗嫉刂返囊弥羔?,也可能是指向一個(gè)代表對(duì)象的句柄或者其他與此對(duì)象相關(guān)的位置)和returnAddress 類(lèi)型(指向了一條字節(jié)碼指令的地址)。

這些數(shù)據(jù)類(lèi)型在局部變量表中的存儲(chǔ)空間以局部變量槽(Slot)來(lái)表示,其中64位長(zhǎng)度的long和 double類(lèi)型的數(shù)據(jù)會(huì)占用兩個(gè)變量槽,其余的數(shù)據(jù)類(lèi)型只占用一個(gè)。局部變量表所需的內(nèi)存空間在編譯期間完成分配,當(dāng)進(jìn)入一個(gè)方法時(shí),這個(gè)方法需要在棧幀中分配多大的局部變量空間是完全確定的,在方法運(yùn)行期間不會(huì)改變局部變量表的大小。

對(duì)這個(gè)內(nèi)存區(qū)域規(guī)定了兩類(lèi)異常狀況:如果線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度,將拋出StackOverflowError異常;如果Java虛擬機(jī)棧容量可以動(dòng)態(tài)擴(kuò)展,當(dāng)棧擴(kuò)展時(shí)無(wú)法申請(qǐng)到足夠的內(nèi)存會(huì)拋出OutOfMemoryError異常。

本地方法棧(Native Method Stacks)與虛擬機(jī)棧所發(fā)揮的作用是非常相似的,其區(qū)別只是虛擬機(jī) 棧為虛擬機(jī)執(zhí)行Java方法(也就是字節(jié)碼)服務(wù),而本地方法棧則是為虛擬機(jī)使用到的本地(Native)方法服務(wù)。 與虛擬機(jī)棧一樣,本地方法棧也會(huì)在棧深度溢出或者棧擴(kuò)展失敗時(shí)分別拋出StackOverflowError和OutOfMemoryError異常。

Java堆(Java Heap)是虛擬機(jī)所管理的內(nèi)存中最大的一塊。Java堆是被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建。此內(nèi)存區(qū)域的唯一目的就是存放對(duì)象實(shí)例,Java世界里“幾乎”所有的對(duì)象實(shí)例都在這里分配內(nèi)存。如果從分配內(nèi)存的角度看,所有線程共享的Java堆中可以劃分出多個(gè)線程私有的分配緩沖區(qū)(Thread Local Allocation Buffer,TLAB),以提升對(duì)象分配時(shí)的效率。當(dāng)前主流的Java虛擬機(jī)都是按照可擴(kuò)展來(lái)實(shí)現(xiàn)的(通過(guò)參數(shù)-Xmx和-Xms設(shè)定)。如果在Java堆中沒(méi)有內(nèi)存完成實(shí)例分配,并且堆也無(wú)法再擴(kuò)展時(shí),Java虛擬機(jī)將會(huì)拋出OutOfMemoryError異常。

方法區(qū)(Method Area)與Java堆一樣,是各個(gè)線程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)已被虛擬機(jī)加載的類(lèi)型信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼緩存等數(shù)據(jù)。

HotSpot虛擬機(jī)設(shè) 計(jì)團(tuán)隊(duì)選擇把收集器的分代設(shè)計(jì)擴(kuò)展至方法區(qū),或者說(shuō)使用永久代來(lái)實(shí)現(xiàn)方法區(qū)而已,這樣使得 HotSpot的垃圾收集器能夠像管理Java堆一樣管理這部分內(nèi)存,省去專(zhuān)門(mén)為方法區(qū)編寫(xiě)內(nèi)存管理代碼的工作。這種設(shè)計(jì)導(dǎo)致了Java應(yīng)用更容易遇到內(nèi)存溢出的問(wèn)題(永久代有-XX:MaxPermSize的上限,即使不設(shè)置也有默認(rèn)大?。?。JDK 8,完全廢棄了永久代的概念,改用與JRockit、J9一樣在本地內(nèi)存中實(shí)現(xiàn)的元空間(Meta- pace)來(lái)代替,把JDK 7中永久代還剩余的內(nèi)容(主要是類(lèi)型信息)全部移到元空間中。 這區(qū)域的內(nèi)存回收目標(biāo)主要是針對(duì)常量池的回收和對(duì)類(lèi)型的卸載,一般來(lái)說(shuō)這個(gè)區(qū)域的回收效果比較難令人滿意,尤其是類(lèi)型的卸載,條件相當(dāng)苛刻,但是這部分區(qū)域的回收有時(shí)又確實(shí)是必要的。

運(yùn)行時(shí)常量池(Runtime Constant Pool)是方法區(qū)的一部分。Class文件中除了有類(lèi)的版本、字段、方法、接口等描述信息外,還有一項(xiàng)信息是常量池表(Constant Pool Table),用于存放編譯期生成的各種字面量與符號(hào)引用,這部分內(nèi)容將在類(lèi)加載后存放到方法區(qū)的運(yùn)行時(shí)常量池中。運(yùn)行時(shí)常量池相對(duì)于Class文件常量池的另外一個(gè)重要特征是具備動(dòng)態(tài)性,Java語(yǔ)言并不要求常量一定只有編譯期才能產(chǎn)生,也就是說(shuō),并非預(yù)置入Class文件中常量池的內(nèi)容才能進(jìn)入方法區(qū)運(yùn)行時(shí)常量池,運(yùn)行期間也可以將新的常量放入池中,這種特性被開(kāi)發(fā)人員利用得比較多的便是String類(lèi)的intern()方法。 既然運(yùn)行時(shí)常量池是方法區(qū)的一部分,自然受到方法區(qū)內(nèi)存的限制,當(dāng)常量池?zé)o法再申請(qǐng)到內(nèi)存時(shí)會(huì)拋出OutOfMemoryError異常。



關(guān)鍵詞:虛擬,理解,深入

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉