Java虛擬機(jī)執(zhí)行Java程序的過(guò)程中,把所有的內(nèi)存劃分成若干個(gè)不同的數(shù)據(jù)區(qū)域。

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