堆記憶體與棧記憶體
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中丟失了物件地址的無用物件清除了),這就是垃圾收集的