溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Java 虛擬機(jī): JVM內(nèi)存分區(qū)及其用途

發(fā)布時(shí)間:2020-07-26 18:00:04 來(lái)源:網(wǎng)絡(luò) 閱讀:143 作者:涼白開(kāi)dream 欄目:編程語(yǔ)言

Java虛擬機(jī)在執(zhí)行Java程序的過(guò)程中會(huì)把它所管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)區(qū),這些區(qū)域都有各自的用途,以及創(chuàng)建和銷(xiāo)毀的時(shí)間,有的區(qū)域隨著虛擬機(jī)進(jìn)程的啟動(dòng)而存在,有些區(qū)域則依賴(lài)用戶(hù)線(xiàn)程的啟動(dòng)和結(jié)束而建立和銷(xiāo)毀。

Java虛擬機(jī)所管理的內(nèi)存將會(huì)包括以下幾個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū)域:

1、程序計(jì)數(shù)器

2、Java虛擬機(jī)棧

3、本地方法棧

4、Java堆

5、方法區(qū)

下面分別介紹各個(gè)內(nèi)存分區(qū)及它們的作用:

1、程序計(jì)數(shù)器

(PC)程序計(jì)數(shù)器是一塊較小的內(nèi)存分區(qū),你可以把它看做當(dāng)前線(xiàn)程所執(zhí)行的字節(jié)碼的指示器。

在虛擬機(jī)的概念模型里,字節(jié)碼指示器工作時(shí),就是通過(guò)改變計(jì)數(shù)器的值來(lái)選擇下一條需要執(zhí)行的字節(jié)碼指令。

程序技術(shù)器為線(xiàn)程私有,每個(gè)線(xiàn)程都有它們各自的程序計(jì)數(shù)器,這樣再多線(xiàn)程的情況下,線(xiàn)程之間的來(lái)回切換,也能正確找到上次切換時(shí)執(zhí)行的位置。(線(xiàn)程隔離的,線(xiàn)程安全的)

如果線(xiàn)程正在執(zhí)行的是一個(gè)Java方法,那么程序計(jì)數(shù)器記錄的是當(dāng)前線(xiàn)程正在執(zhí)行的字節(jié)碼指令的地址;如果線(xiàn)程正在執(zhí)行的是一個(gè)native方法,則計(jì)數(shù)器值為空。

此內(nèi)存區(qū)域是唯一一個(gè)Java虛擬機(jī)規(guī)范中沒(méi)有規(guī)定任何內(nèi)存泄漏OutOfMemoryError(OOM)情況的區(qū)域。

2、Java虛擬機(jī)棧

虛擬機(jī)棧也為線(xiàn)程私有的,它的生命周期與線(xiàn)程相同;

虛擬機(jī)??梢钥醋鍪荍ava方法執(zhí)行的內(nèi)存模型:每個(gè)方法執(zhí)行的同時(shí)都會(huì)創(chuàng)建一個(gè)棧幀用于存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等信息。一個(gè)Java方法從調(diào)用到執(zhí)行完的過(guò)程,就對(duì)應(yīng)著一個(gè)棧幀從虛擬機(jī)棧入棧到出棧的過(guò)程;

局部變量表中存放了編譯期可知的基本數(shù)據(jù)類(lèi)型、對(duì)象引用、returnAddress類(lèi)型(指向了一條字節(jié)碼指令的地址);

在虛擬機(jī)棧中可能會(huì)出現(xiàn)兩種異常:StackOverflowError和OutOfMemory。

StackOverflowError:如果線(xiàn)程請(qǐng)求的棧深度大于當(dāng)前虛擬機(jī)所允許的深度,會(huì)拋出該異常;

OutOfMemory:如果虛擬機(jī)??梢詣?dòng)態(tài)擴(kuò)展,當(dāng)擴(kuò)展時(shí)無(wú)法申請(qǐng)到足夠的內(nèi)存,會(huì)拋出該異常;

3、本地方法棧

本地方法棧類(lèi)似與虛擬機(jī)棧,它們不同之處在于,虛擬機(jī)棧是為虛擬機(jī)執(zhí)行的Java方法服務(wù),而本地方法棧是為虛擬機(jī)使用到的Native方法服務(wù);

在本地方法??赡軙?huì)出現(xiàn)兩種異常:StackOverflowError和OutOfMemory

4、Java堆

Java堆是被所有線(xiàn)程共享的一塊區(qū)域,它也是Java虛擬機(jī)管理的內(nèi)存中最大的一塊,它在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建;

Java堆唯一的目的就是存放對(duì)象實(shí)例
,幾乎所有的對(duì)象實(shí)例的都在這里分配內(nèi)存;

Java堆是垃圾收集器管理的主要區(qū)域,因此很多時(shí)候也被稱(chēng)為GC堆;

Java堆可以處于物理上不連續(xù)的內(nèi)存空間中,只要邏輯上連續(xù)即可,在實(shí)現(xiàn)時(shí)既可以是固定大小也可以是可擴(kuò)展的,如果堆中沒(méi)有內(nèi)存完成實(shí)例分配,并且堆也無(wú)法再擴(kuò)展時(shí),將會(huì)拋出OutOfMemory異常;

5、方法區(qū)(運(yùn)行時(shí)常量池)

方法區(qū)也是內(nèi)存共享的一塊區(qū)域,它用于存放已被虛擬機(jī)加載的類(lèi)信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù);

方法區(qū)中,垃圾收集比較少見(jiàn),但并不是不進(jìn)行GC,這個(gè)區(qū)域的回收目標(biāo)主要是針對(duì)常量池的回收和對(duì)類(lèi)型的卸載

方法區(qū)類(lèi)似于Java堆,不要連續(xù)的內(nèi)存和可以選擇固定大小或者可擴(kuò)展。它還可以選擇不實(shí)現(xiàn)垃圾收集;

當(dāng)方法區(qū)無(wú)法滿(mǎn)足內(nèi)存分配需求時(shí),會(huì)拋出OutOfMemory異常;

方法區(qū)中還存在一個(gè)運(yùn)行時(shí)常量池(無(wú)關(guān)乎線(xiàn)程安全與否)(因?yàn)槠鋽?shù)據(jù)不能更改),常量池用于存放編譯期生成的各種字面量和符號(hào)引用,它具有動(dòng)態(tài)性,不要求常量一定只有編譯期才能產(chǎn)生,運(yùn)行期間也可能將新的常量放入池中;

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI