Java虛擬機執行Java程序的過程中,把所有的內存劃分成若干個不同的數據區域。
程序計數器
在虛擬機概念模型里,字節碼解釋器工作時就通過改變程序的計數器的值來選取下一條執行的字節碼指令。(永遠指下一條需要執行的指令)
Java虛擬機的多線程,通過線程輪流切換并分處理器的方式來實現的,在任何一個確定的時刻,一個處理器智慧執行一個線程的一條指令。為了保證線程切換以后程序恢復到正確的執行位置來正常執行,每條線程的計數器都是獨立存儲的,互不影響的,也就是說”計數器是線程私有的”。
小總結:
–每個線程擁有一個計數器
–在線程創建時創建(與線程同生共死)
–指向下一條指令的地址
–執行本地方法時,PC的值為undefined
Java虛擬機棧
Java虛擬機棧也跟程序計數器一樣線程私有的,它的生命周期跟線程一樣,與線程同生共死。Java虛擬機棧描述的是Java方法執行的內存模型:每個方法執行時創建一個棧幀用于存儲局部變量表,操作棧,方法出口信息等。方法調用過程對應棧幀入棧到出棧的過程中。
局部變量表存放著各種編譯器可知的基本變量類型,對象引用(指針地址)和returnAddress類型。
需要記住一下幾點:
–線程私有
–棧由一系列幀組成(因此Java棧也叫做幀棧)
–幀保存一個方法的局部變量、操作數棧、常量池指針
–每一次方法調用創建一個幀,并壓棧
Java堆
Java堆是線程共享的一塊內存區域,Java虛擬機啟動時創建,虛擬機內最大的內存管理區域。主要存放對象實例(new出來的對象存放到堆里)。Java堆是垃圾回收器管理的主要區域,因此也被稱作“GC堆”。Java堆內存分配物理上不連續的,邏輯上連續的。
需要記住一下幾點:
–和程序開發密切相關
–應用系統對象都保存在Java堆中
–所有線程共享Java堆
–對分代GC來說,堆也是分代的
–GC的主要工作區間
方法區
方法去也跟java堆一樣也是線程共享的內存區域。一般用于存放虛擬機加載的類信息,靜態變量,常量。垃圾收集器的行為在方法區內比較少見,所以很多人成為“永久區”,其實永久區和方法區不等價的。虛擬機里也不存在永久區。
需要記住的幾點:
–保存裝載的類信息
?類型的常量池
?字段,方法信息
?方法字節碼
–通常和永久區(Perm)關聯在一起
public? class AppMain{
//運行時, jvm把appmain的信息都放入方法區
? public? static? void? main(String[] args){
? ? ? //main方法本身放入方法區。
? ? ? ?Sample test1 = new? Sample( "測試1 ");
? ? ? //test1是引用,所以放到棧區里,Sample是自定義對象應該放到堆里面
? ? ? Sample test2 = new? Sample( "測試2 ");
? ? ? test1.printName();
? ? ? ?test2.printName();
? }
}
public? class Sample{
//運行時, jvm把appmain的信息都放入方法區
? ? ? private? name;
? ? //newSample實例后,name引用放入棧區里,name對象放入堆里
? ? public? Sample(String name){
? ? ? ? ? this .name = name;
? ? }
? ? //print方法本身放入 方法區里。
? ? public?? void? printName(){
? ? ? ? ? ?System.out.println(name);
? ? }
?}