Java虛擬機在執(zhí)行Java程序的過程中會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域。不同的區(qū)域有不同的用途,它們的創(chuàng)建和銷毀的時間點也有不同,這個就是該篇文章所要講述的內(nèi)容。
運行時數(shù)據(jù)區(qū)域
由所有線程共享的數(shù)據(jù)區(qū)域:方法區(qū)、Java堆。這些區(qū)域隨著虛擬機的啟動而生成。
??線程隔離的數(shù)據(jù)區(qū)域:本地方法棧、Java虛擬機棧、程序計數(shù)器。這些區(qū)域依賴用戶線程的啟動和結(jié)束來建立和銷毀。

1、Java堆(Java Heap)
Java堆唯一的目的是存放對象實例和數(shù)組。同時,Java堆也是垃圾收集器管理的主要區(qū)域,很多時候也稱為 GC堆(Garbage Collected Heap) **
2、方法區(qū)(Method Area)
方法區(qū)用于存儲已被虛擬機加載的類信息、常量、靜態(tài)變量、即時編譯器編譯后的代碼等數(shù)據(jù)。Java虛擬機規(guī)范將方法區(qū)描述為堆的一個邏輯部分,但是它卻有一個別名叫做Non-Heap,目的應該是與Java堆區(qū)分開來。
??方法區(qū)中還有一個特殊的部分 —— 運行時常量池。Class文件除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池(Constant Pool Table),用于存放編譯期生成的各種字面量和符號引用,這部分內(nèi)容在類加載后存放到方法區(qū)的運行時常量池中。
??運行時常量池另外一重要特征是動態(tài)性,Java語言并不要求常量一定只能在編譯期間產(chǎn)生,運行期間也可能將新的常量放入池中,這種特性可以體現(xiàn)在 String 類的 intern() 方法
3、Java虛擬機棧(Java Virtual Machine Stacks)
虛擬機棧描述的Java方法執(zhí)行的內(nèi)存模型:每個方法被執(zhí)行的時候都會同時創(chuàng)建一個棧幀(Stack Frame)**用于存儲局部變量表、操作棧、動態(tài)鏈接、方法出口等信息。每個方法被調(diào)用的過程對應著一個棧幀在虛擬機棧中從入棧到出棧的過程。
4、本地方法棧(Native Method Stacks)
本地方法棧與虛擬機棧功能相似,區(qū)別在于虛擬機棧執(zhí)行Java方法(也就是字節(jié)碼)服務,而本地方法棧則是為虛擬機使用到的Native方法服務。一些虛擬機(例如:Sun HotSpot虛擬機)直接把本地方法棧與虛擬機棧合二為一。
5、程序計數(shù)器(Program Couter Register)
程序計數(shù)器可以看做是當前線程所執(zhí)行的字節(jié)碼的行號指示器。所以在執(zhí)行Java方法與Native方法的時候程序計數(shù)器的處理方式不一樣:
??如果線程正在執(zhí)行的是一個Java方法,這個計數(shù)器記錄的是正在執(zhí)行的虛擬機字節(jié)碼的地址;如果正在執(zhí)行的Native方法,這個計數(shù)器值則為空。
參考資料:《深入理解Java虛擬機:JVM高級特性與最佳實踐》 ------ 周志明