1. 程式人生 > >Java 堆和棧的區別

Java 堆和棧的區別

  1. 實體地址 a. 堆的實體地址分配對物件是不連續的。因此效能慢些。在GC的時候也要考慮到不連續的分配,所以有各種垃圾收集演算法。比如,標記-消除,複製,標記-整理,分代(即新生代使用複製演算法,老年代使用標記——壓縮) b. 棧使用的是資料結構中的棧,先進後出的原則,實體地址分配是連續的。所以效能快。

  2. 記憶體分配 a. 堆因為是不連續的,所以分配的記憶體是在執行期確認的,因此大小不固定。 b. 棧是連續的,所以分配的記憶體大小要在編譯期就確認,大小是固定的。

  3. 存放的內容 a. 堆存放的是物件的例項和陣列。因此該區更關注的是資料的儲存 b. 棧存放:區域性變數,運算元棧,返回結果。該區更關注的是程式方法的執行。主要存放一些基本型別的變數(int, short, long, byte, float, double, boolean, char)和物件控制代碼

PS:靜態變數放在方法區,靜態的物件還是放在堆。

  1. 私有還是共享 a. 棧記憶體歸屬於單個執行緒,每個執行緒都會有一個棧記憶體,其儲存的變數只能在其所屬執行緒中可見,即棧記憶體可以理解成執行緒的私有記憶體。 b. 堆記憶體中的物件對所有執行緒可見。堆記憶體中的物件可以被所有執行緒訪問。

  2. 異常錯誤 a. 當Stack滿了,Java Runtime會丟擲java.lang.StackOverFlowError。 b. 當Heap滿了,會丟擲java.lang.OutOfMemoryError: Java Heap Space Error。