1. 程式人生 > >堆記憶體與棧記憶體

堆記憶體與棧記憶體

java的記憶體分為堆記憶體和棧記憶體

 

棧記憶體是指程式進入一個方法時,會為這個方法單獨分配一塊私屬儲存空間,用於儲存這個方法內部的區域性變數,當這個方法結束時,分配給這個方法的棧會釋放,這個棧中的變數也將隨之釋放。

堆是與棧作用不同的記憶體,一般用於存放不放在當前方法棧中的那些資料,例如,使用new建立的物件都放在堆裡,所以,它不會隨方法的結束而消失。方法中的區域性變數使用final修飾後,放在堆中,而不是棧中。

 

JVM空間分配

heap是堆:1、手動申請和釋放空間     2、大自由區

stack是棧:1、自動分配和釋放    2、空間有限

例:在Java中,若只是宣告一個物件,則先在棧記憶體中為其分配地址空間,若再new一下,例項化它,則在堆記憶體中為其分配地址。

Object a=null;只在棧中分配記憶體。

new Object();在堆中分配空間。

Object b =new Object();在棧中分配空間,指向堆中的地址。

記憶體中堆疊的關係

Heap是 Stack的一個子集。

Stack存取速度僅次於暫存器,儲存效率比heap高,可共享儲存資料,但是其中資料的大小和生存期必須在執行前確定。

Heap是執行時可動態分配的資料區,從速度看比Stack慢,Heap裡面的資料不共享,大小和生存期都可以在執行時再確定。

new關鍵字 是執行時在Heap裡面建立物件,每new一次都一定會建立新物件,因為堆資料不共享。

回收上區別

Stack的記憶體管理是順序分配的,而且定長,不存在記憶體回收問題

Heap 則是隨機分配記憶體,不定長度,存在記憶體分配和回收的問題

在JVM中另有一個GC程序,定期掃描Heap ,它根據Stack中儲存的4位元組物件地址掃描Heap ,定位Heap 中這些物件,進行一些優化(例如合併空閒記憶體塊什麼的),並且假設Heap 中沒有掃描到的區域都是空閒的,統統refresh(實際上是把Stack中丟失了物件地址的無用物件清除了),這就是垃圾收集的