
一、 程序計(jì)數(shù)器
記錄正在執(zhí)行的虛擬機(jī)字節(jié)碼指令的地址(如果正在執(zhí)行的是本地方法則為空)
二、 Java 虛擬機(jī)棧
每個(gè)Java方法在執(zhí)行的同時(shí)會(huì)創(chuàng)建一個(gè)棧幀用于存儲(chǔ)局部變量表、操作數(shù)棧、常量池引用等信息。從方法調(diào)用直至執(zhí)行完成的過(guò)程,對(duì)應(yīng)著一個(gè)棧幀在Java虛擬機(jī)中入棧和出棧的過(guò)程。

可以通過(guò)-Xss這個(gè)虛擬機(jī)參數(shù)來(lái)指定每個(gè)線程的Java虛擬機(jī)內(nèi)存大小,在JDK1.4中默認(rèn)為256K,而在JDK1.5+默認(rèn)為1M:
java -Xss2m HackTheJava
該區(qū)域可能拋出如下異常:
- 當(dāng)線程請(qǐng)求的棧的深度超過(guò)最大值,會(huì)拋出
StackOverflowError異常; - 棧進(jìn)行動(dòng)態(tài)擴(kuò)展時(shí)如果無(wú)法申請(qǐng)到足夠內(nèi)存,會(huì)拋出
OutOfMemoryError異常。
三、本地方法棧
本地方法棧與Java虛擬機(jī)棧類似,它們之間的區(qū)別只不過(guò)是本地方法棧為本地方法服務(wù)。
本地方法一般是用其它語(yǔ)言(C, C++或匯編語(yǔ)言等)編寫(xiě)的,并且被編譯為基于本機(jī)硬件和操作系統(tǒng)的程序,對(duì)待這些方法需要特別處理。

四、堆
所有對(duì)象都在這里分配內(nèi)存,是垃圾收集的主要區(qū)域(“GC 堆”)。
現(xiàn)代的垃圾收集器基本都是采用分代收集算法,其主要思想是針對(duì)不同類型的對(duì)象采取不同的垃圾回收算法。可以將堆分成兩塊:
- 新生代(Young Generation)
- 老年代(Old Generation)
堆不需要連續(xù)內(nèi)存,并且可以動(dòng)態(tài)增加其內(nèi)存,增加失敗會(huì)拋出OutOfMemoryError異常。
可以通過(guò)-Xms和-Xmx這兩個(gè)虛擬機(jī)參數(shù)來(lái)指定一個(gè)程序的堆內(nèi)存大小,第一個(gè)參數(shù)設(shè)置初始值,第二個(gè)參數(shù)設(shè)置最大值。
java -Xms1M -Xmx2M HackTheJava
五、方法區(qū)
用于存放已被加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。
和堆一樣不需要連續(xù)的內(nèi)存,并且可以動(dòng)態(tài)擴(kuò)展,動(dòng)態(tài)擴(kuò)展失敗一樣會(huì)拋出OutOfMemoryError異常。
對(duì)這塊區(qū)域進(jìn)行垃圾回收的主要目標(biāo)是對(duì)常量池的回收和對(duì)類的卸載,但是一般比較難實(shí)現(xiàn)。
Hotspot虛擬機(jī)把它當(dāng)成永久代來(lái)進(jìn)行垃圾回收。但是很難確定永久代的大小,因?yàn)樗艿胶芏嘁蛩赜绊?,并且每次Full GC之后永久代的大小都會(huì)改變,所以經(jīng)常會(huì)拋出OutOfMemoryError異常。為了更容易管理方法區(qū),從JDK1.8開(kāi)始,移除永久代,并把方法區(qū)移至元空間,它位于本地內(nèi)存中,而不是虛擬機(jī)內(nèi)存中。
方法區(qū)是一個(gè)JVM規(guī)范,永久代和元空間都是其一種實(shí)現(xiàn)方式。在JDK1.8之后,原來(lái)永久代的數(shù)據(jù)被分到堆和元空間中。元空間存儲(chǔ)類的元信息,靜態(tài)變量和常量池放入堆中。
六、運(yùn)行時(shí)常量池
運(yùn)行時(shí)常量池是方法區(qū)的一部分。
Class 文件中的常量池(編譯器生成的字面量和符號(hào)引用)會(huì)在類加載后被放入這個(gè)區(qū)域。
七、直接內(nèi)存
在 JDK 1.4 中新引入了 NIO 類,它可以使用 Native 函數(shù)庫(kù)直接分配堆外內(nèi)存,然后通過(guò) Java 堆里的 DirectByteBuffer 對(duì)象作為這塊內(nèi)存的引用進(jìn)行操作。這樣能在一些場(chǎng)景中顯著提高性能,因?yàn)楸苊饬嗽诙褍?nèi)存和堆外內(nèi)存來(lái)回拷貝數(shù)據(jù)。