JVM內(nèi)存區(qū)域結(jié)構(gòu):一計(jì)兩棧一堆一區(qū)
1程序計(jì)數(shù)器
- 一塊較小的內(nèi)存空間。
- 當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器。
2虛擬機(jī)棧
描述的是Java方法執(zhí)行的線程內(nèi)存模型:每個(gè)方法被執(zhí)行的時(shí)候,Java虛擬機(jī)都會(huì)同步創(chuàng)建一個(gè)棧(StackFrame)用于存儲(chǔ)局部變量表、操作數(shù)棧、 動(dòng)態(tài)連接、方法出口等信息。每一個(gè)方法被調(diào)用直至執(zhí)行完畢的過(guò)程,就對(duì)應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中從入棧到出棧的過(guò)程。
局部變量表(存放)
- 基本數(shù)據(jù)類型
- 對(duì)象引用
- returnAddress類型(指向了一條字節(jié)碼指令的地址)
異常
StackOverflowError:線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度
OutOfMemoryError:棧擴(kuò)展時(shí)無(wú)法申請(qǐng)到足夠的內(nèi)存
3本地方法棧
虛擬機(jī)使用到的本地(Native)方法服務(wù)。
4Java堆回收內(nèi)存的角度
新生代、老年代、永久代、Eden空間、From Survivor空間、To Survivor空間。
分配內(nèi)存的角度
所有線程共享的Java堆中可以劃分出多個(gè)線程私有的分配緩沖區(qū)(Thread Local Allocation Buffer,TLAB)。
異常
OutOfMemoryError:沒(méi)有內(nèi)存完成實(shí)例分配, 并且堆也無(wú)法再擴(kuò)展時(shí)
5方法區(qū)
- 各個(gè)線程共享的內(nèi)存區(qū)域
- 用于存儲(chǔ)已被虛擬機(jī)加載的類型信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼緩存等數(shù)據(jù)
- JDK8將永久代廢棄,相應(yīng)的用元空間MetaSpace
異常
OutOfMemoryError:無(wú)法滿足新的內(nèi)存分配需求時(shí)
6運(yùn)行時(shí)常量池
- 方法區(qū)的一部分
- 用于存放編譯期生成的各種字面量與符號(hào)引用, 這部分內(nèi)容將在類加載后存放到方法區(qū)的運(yùn)行時(shí)常量池中
異常
OutOfMemoryError:當(dāng)常量池?zé)o法再申請(qǐng)到內(nèi)存
7直接內(nèi)存
不是虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)的一部分
本機(jī)直接內(nèi)存的分配不會(huì)受到Java堆大小的限制
總結(jié):
JVM內(nèi)存區(qū)域結(jié)構(gòu)包含:程序計(jì)數(shù)器、虛擬機(jī)棧、本地方法棧、Java堆、方法區(qū)??梢院?jiǎn)記為:一計(jì)兩棧一堆一區(qū),方便記憶。
方法區(qū)包含運(yùn)行時(shí)常量池,還有直接內(nèi)存(NIO更常見(jiàn))。
需要了解到每個(gè)區(qū)域是主要作用是什么,這樣才能更加牢固的掌握。