一、運(yùn)行時(shí)數(shù)據(jù)區(qū)域
JVM_Runtime-Data-Area.jpg
1.1苍柏、程序計(jì)數(shù)器
當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器。
- 一塊很小的內(nèi)存空間姜贡,速度最快的存儲區(qū)域试吁。
- 在JVM規(guī)范中,每個(gè)線程都有他自己的程序計(jì)數(shù)器楼咳,是線程私有的熄捍,生命周期與線程的生命周期保持一致。
- 任何時(shí)候一個(gè)線程都只有一個(gè)方法在執(zhí)行母怜,也就是所謂的當(dāng)前方法余耽。程序計(jì)數(shù)器會存儲當(dāng)前線程正在執(zhí)行的Java方法的JVM指令的地址;或者如果在執(zhí)行的是native方法糙申,則是未指定值(undefind)宾添。
- 它是程序控制流的指示器船惨,分支,循環(huán)缕陕,跳轉(zhuǎn)粱锐,異常處理,線程恢復(fù)等基礎(chǔ)功能都是需要依賴這個(gè)計(jì)數(shù)器來完成扛邑。
- 字節(jié)碼解釋器工作時(shí)就是通過改變這個(gè)計(jì)數(shù)器的值來選取下一條需要執(zhí)行的字節(jié)碼指令怜浅。
- 唯一一個(gè)在Java虛擬機(jī)規(guī)范中沒有規(guī)定任何OutMemoryError情況的區(qū)域。
使用 PC計(jì)數(shù)器 存儲字節(jié)碼指令地址有什么用蔬崩?
CPU需要不停的切換各個(gè)線程恶座,切換回來以后,就得知道接著從哪里開始繼續(xù)執(zhí)行
1.2沥阳、Java 虛擬機(jī)棧
- 線程私有跨琳,它的生命周期與線程相同。
- 每個(gè)方法被執(zhí)行的時(shí)候桐罕,Java 虛擬機(jī)棧都會同步創(chuàng)建一個(gè)棧幀
Stack Frame
用于存儲局部變量表脉让、操作數(shù)棧、動態(tài)連接功炮、方法出口等信息溅潜。每個(gè)方法被調(diào)用直至執(zhí)行完畢的過程,就對應(yīng)著一個(gè)棧幀在虛擬機(jī)棧中從入棧到出棧的過程薪伏。 - 該區(qū)域可能產(chǎn)生兩類異常:
- 如果線程請求的棧深度大于虛擬機(jī)所允許的深度滚澜,拋出
StackOverflowError
異常; - 如果 Java 虛擬機(jī)棧容量可以動態(tài)擴(kuò)展嫁怀,當(dāng)棧擴(kuò)展時(shí)無法申請到足夠的內(nèi)存會拋出
OutOfMemoryError
異常设捐。
- 如果線程請求的棧深度大于虛擬機(jī)所允許的深度滚澜,拋出
1.3、本地方法棧
- 為虛擬機(jī)使用到的本地(Native)方法服務(wù)塘淑。
- 可能產(chǎn)生兩類異常:
StackOverflowError
和OutOfMemoryError
異常挡育。
1.4、Java 堆
- 物理上不連續(xù)朴爬,但在邏輯上連續(xù)的內(nèi)存空間
1.5即寒、方法區(qū)/元數(shù)據(jù)區(qū)
- 存儲已被虛擬機(jī)加載的類型信息、常量召噩、靜態(tài)變量母赵、即時(shí)編譯器編譯后的代碼緩存等數(shù)據(jù)。
1.6具滴、運(yùn)行時(shí)常量池
- 是方法區(qū)的一部分凹嘲。
1.7、直接內(nèi)存
- 使用 Native 函數(shù)庫直接分配對外內(nèi)存构韵,然后通過堆內(nèi)的
DirectByteBuffer
對象作為這塊內(nèi)存的引用進(jìn)行操作周蹭。 - 不受 Java 堆大小限制趋艘,受物理內(nèi)存大小限制。