例:在new完一個具name和age兩個屬性的P后棧和堆得關系如下圖所示:

那么為什么要有這種設計原理呢?從軟件設計的角度看,棧代表了處理邏輯,而堆代表了數據。這樣分開,使得處理邏輯更為清晰,分而治之的思想。這種隔離、模塊化的思想在軟件設計的方方面面都有體現。 堆與棧分離,使得堆中的內容可以被多個棧共享(也可以理解為多個線程訪問同一個對象)這種共享的收益是很多的,一方面這種共享提供了一種有效的數據交互(共享內存),另一方面,堆中的共享常量和緩存可以被所有棧訪問,節省了空間。 棧因為運行時的需要,比如保存系統運行的上下文,需要進行地址段的劃分。由于棧只能向上增長,因此就會限制住棧存儲內容的能力。而堆不同,堆中的對象是可以根據需要動態增長的,因此棧和堆的拆分,使得動態增長成為可能,相應棧中只需記錄堆中的一個地址即可。 Java 的堆是一個運行時數據區,類的對象從中分配空間。這些對象通過new、newarray、anewarray和multianewarray等指令建立,它們不需要程序代碼來顯式的釋放。 堆是由垃圾回收來負責的,堆的優勢是可以動態地分配內存大小,生存期也不必事先告訴編譯器,因為它是在運行時動態分配內存的,Java的垃圾收集器會自動收走這些不再使用的數據。但缺點是,由于要在運行時動態分配內存,存取速度較慢。 棧的優勢是,存取速度比堆要快,僅次于寄存器,棧數據可以共享。但缺點是,存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。棧中主要存放一些基本類型的變量(int, short, long, byte, float, double, boolean, char)和對象句柄。
例:在new完兩個具name和age兩個屬性的P1和P2后,內存會發生如下變化:

當執行P2 = P1時,指向將會發生變化:

當先執行P1.name = "price";P1.age=43后堆內存改變,但是執行完P2.name = "soap";P2.age = 23后堆內存則發生如下改變,原先P2所指的那塊堆內存則成為垃圾,又GC進行回收:
