1. 程式人生 > >Java小題目之heap和stack的區別

Java小題目之heap和stack的區別

heap和stack的區別

  1. 棧(stack)與堆(heap)都是Java用來在Ram中存放資料的地方。Java自動管理棧和堆,程式設計師不能直接地設定棧或堆。

  2. 每個應用程式執行時,都有屬於自己的一段記憶體空間,用於存放一些基本型別的變數、物件的引用變數、引數傳遞、函式呼叫時的PC值的儲存。這叫棧(stack)。

  3. 所有的應用可以從一個系統共用的空間中申請供自己使用的記憶體,用來存放由new建立的物件和陣列,這個共用的空間叫堆(heap)。

  4. 在堆中產生了一個數組或物件後,還可以在棧中定義一個特殊的變數,讓棧中這個變數的取值等於陣列或物件在堆記憶體中的首地址,棧中的這個變數就成了陣列或物件的引用變數。引用變數就相當於是為陣列或物件起的一個名稱,以後就可以在程式中使用棧中的引用變數來訪問堆中的陣列或物件。

  5. 棧的優勢是,存取速度比堆要快,僅次於直接位於CPU中的暫存器。但缺點是,存在棧中的資料大小與生存期必須是確定的,缺乏靈活性。

  6. 堆的優勢是可以動態地分配記憶體大小,生存期也不必事先告訴編譯器,Java的垃圾收集器會自動收走這些不再使用的資料。但缺點是,由於要在執行時動態分配記憶體,存取速度較慢。

Java中變數在記憶體中的分配

  1. 類變數(static修飾的變數):在程式載入時系統就為它在堆中開闢了記憶體,堆中的記憶體地址存放於棧以便於高速訪問。靜態變數的生命週期–一直持續到整個”系統”關閉。

  2. 例項變數:當你使用java關鍵字new的時候,系統在堆中開闢並不一定是連續的空間分配給變數(比如說類例項),然後根據零散的堆記憶體地址,通過雜湊演算法換算為一長串數字以表徵這個變數在堆中的”物理位置”。 例項變數的生命週期–當例項變數的引用丟失後,將被GC(垃圾回收器)列入可回收“名單”中,但並不是馬上就釋放堆中記憶體。

  3. 區域性變數:區域性變數,由宣告在某方法,或某程式碼段裡(比如for迴圈),執行到它的時候在棧中開闢記憶體,當局部變數一但脫離作用域,記憶體立即釋放。