##虛擬機器記憶體結構
###程式計數器 執行緒私有的,學過ARM或者彙編的同學應該很熟悉,表示的是當前執行緒執行到了哪一行位元組碼。
java虛擬機器棧
“java虛擬機器棧”這個名字很讓人誤會,看起來一點都不像是執行緒私有的,看起來像是“虛擬機器”級別的東西,更像是執行緒共享的,但實際上它確實是執行緒私有的,所以我覺得它更應該叫做“執行緒棧”諸如此類更加“人如其名”的稱呼。“java虛擬機器棧”的生命週期是和執行緒相同的,執行緒執行某個方法的時候會為方法建立一個叫做“棧幀”的資料結構進行入棧,這個“棧幀”用來記錄方法的區域性變數等資訊。“java虛擬機器棧”深度是有限的,如果一個執行緒在呼叫方法數超過棧所能容納的深度時候會出現StackOverflowError,告訴你棧爆了,怎麼模擬這種情況呢,哈哈,執行沒有遞迴終止條件的遞迴方法,如下:
public class App {
public static int f(int num) {
// 把遞迴終止條件去掉
// if(num>10){
// System.out.println("----->"+num);
// return num;
// }
num++;
return f(num);
}
public static void main(String[] args) {
f(0);
}
}
複製程式碼
執行上述程式碼會出現StackOverflowError,如下:
本地方法棧
又是一個棧,還是本地的(native),容易想到這是一個與本地方法有關的棧,實際上確實如此,本地方法棧與java虛擬機器棧發揮的作用是非常相似的,它們的區別在於虛擬機器棧是為java方法服務,本地方法棧為本地方法服務,所以本地方法棧也是執行緒私有的。
java堆
java堆是執行緒共享的用來儲存類例項和陣列物件的(但不是唯一不能夠類例項和陣列物件)儲存區域。java堆上的物件生命週期不一,有長有短,為了提高回收效率,採用了分代收集的策略。這裡的“代”可以分為“新生代”、“老年代”
方法區
執行緒共享的用來儲存系統的類資訊(包括類的欄位、方法、常量池、靜態變數)的儲存區域,方法區也叫永久代,這個是因為它不像java堆一樣被Gc回收得那麼頻繁,但也不是說不能被回收,如果一個類不在被“引用”,這個類就應該從虛擬機器解除安裝,被解除安裝的類是可以被回收的,如果系統的類太多的話也會導致方法去溢位。