詳情參考:https://my.oschina.net/wangsifangyuan/blog/711329
前言:當要判斷一個變量存在什么空間上哪兒時,先分析它是哪一種(是實例變量還是局部變量),實例變量存在於所屬的對象中,因此在創建對象后才存在,存在於堆上;
如果為局部變量,局部變量是被聲明在方法中的,它是暫時的,且生命周期只限於方法被放於棧上的這段期間(方法調用至執行完畢),因此存在於棧上;
堆區:
1.存儲的全部是對象,每個對象都包含一個與之對應的class的信息。(class的目的是得到操作指令)
2.jvm只有一個堆區(heap)被所有線程共享,堆中不存放基本類型和對象引用,只存放對象本身
棧區:
1.每個線程包含一個棧區,棧中只保存基礎數據類型的對象和自定義對象的引用(不是對象),對象都存放在堆區中
2.每個棧中的數據(原始類型和對象引用)都是私有的,其他棧不能訪問。
3.棧分為3個部分:基本類型變量區、執行環境上下文、操作指令區(存放操作指令)。
方法區:
1.又叫靜態區,跟堆一樣,被所有的線程共享。方法區包含所有的class和static變量。
2.方法區中包含的都是在整個程序中永遠唯一的元素,如class,static變量。
注意容易入坑的地方:
1、棧上只保存基礎數據類型的對象和自定義對象的引用(對的),但是不是說基礎數據類型的對象和自定義對象的引用只保存在棧上(這是錯的)
1 public class Student{ 2 private int age; 3}
1 public void go(){ 2 Student students[] = new Student[3]; 3 students[0] = new Student(); 4 students[0].age = 20; 5 students[1] = new Student(); 6 students[1].age = 20; 7 students[2] = new Student(); 8 students[2].age = 20; 9 int a = 10; 10 }