1. 程式人生 > >棧、堆記憶體區別

棧、堆記憶體區別

Java把記憶體分成兩種,一種叫做棧記憶體,一種叫做堆記憶體。

在函式中定義的一些基本型別的變數和物件的引用變數都是在函式的棧記憶體中分配。當在一段程式碼塊中定義一個變數時,java就在棧中為這個變數分配記憶體空間,當超過變數的作用域後,java會自動釋放,該記憶體空間可以立刻被另作他用。

堆記憶體用於存放由new建立的物件和陣列。在堆中分配的記憶體,由java虛擬機器自動垃圾回收器來管理。在堆中產生了一個數組或者物件後,還可以在棧中定義一個特殊的變數,這個變數的取值等於陣列或者物件在堆記憶體中的首地址,在棧中的這個特殊的變數就變成了陣列或者物件的引用變數(類於指標),以後就可以在程式中使用棧記憶體中的引用變數來訪問堆中的陣列或者物件,引用變數相當於為陣列或者物件起的一個別名,或者代號。

引用變數是普通變數,定義時在棧中分配記憶體,引用變數在程式執行到作用域外釋放。而陣列&物件本身在堆中分配,即使程式執行到使用new產生陣列和物件的語句所在地程式碼塊之外,陣列和物件本身佔用的堆記憶體也不會被釋放,陣列和物件在沒有引用變數指向它的時候(比如先前的引用變數x=null時),才變成垃圾,不能再被使用,但是仍然佔著記憶體,在隨後的一個不確定的時間被垃圾回收器釋放掉。這個也是java比較佔記憶體的主要原因。

總結起來就是物件儲存在堆記憶體,引用變數儲存在棧記憶體。棧記憶體指向堆記憶體。