當一個人開始學習Java或者其他編程語言的時候,會接觸到堆和棧,由於一開始沒有明確清晰的說明解釋,很多人會產生很多疑問,什麼是堆,什麼是棧,堆和棧有什麼區別?更糟糕的是,Java中存在棧這樣一個後進先出(Last In First Out)的順序的數據結構,這就是java.util.Stack。這種
當一個人開始學習Java或者其他編程語言的時候,會接觸到堆和棧,由於一開始沒有明確清晰的說明解釋,很多人會產生很多疑問,什麼是堆,什麼是棧,堆和棧有什麼區別?更糟糕的是,Java中存在棧這樣一個後進先出(Last In First Out)的順序的數據結構,這就是java.util.Stack。這種情況下,不免讓很多人更加費解前面的問題。事實上,堆和棧都是記憶體中的一部分,有著不同的作用,而且一個程式需要在這片區域上分配記憶體。眾所周知,所有的Java程式都運行在JVM虛擬機內部,我們這裡介紹的自然是JVM(虛擬)記憶體中的堆和棧。
區別
java中堆和棧的區別自然是面試中的常見問題,下麵幾點就是其具體的區別
各司其職
最主要的區別就是棧記憶體用來存儲局部變數和方法調用。
而堆記憶體用來存儲Java中的對象。無論是成員變數,局部變數,還是類變數,它們指向的對象都存儲在堆記憶體中。
獨有還是共用
棧記憶體歸屬於單個線程,每個線程都會有一個棧記憶體,其存儲的變數只能在其所屬線程中可見,即棧記憶體可以理解成線程的私有記憶體。
而堆記憶體中的對象對所有線程可見。堆記憶體中的對象可以被所有線程訪問。
異常錯誤
如果棧記憶體沒有可用的空間存儲方法調用和局部變數,JVM會拋出java.lang.StackOverFlowError。
而如果是堆記憶體沒有可用的空間存儲生成的對象,JVM會拋出java.lang.OutOfMemoryError。
空間大小
棧的記憶體要遠遠小於堆記憶體,如果你使用遞歸的話,那麼你的棧很快就會充滿。如果遞歸沒有及時跳出,很可能發生StackOverFlowError問題。
你可以通過-Xss選項設置棧記憶體的大小。-Xms選項可以設置堆的開始時的大小,-Xmx選項可以設置堆的最大值。
這就是Java中堆和棧的區別。理解好這個問題的話,可以對你解決開發中的問題,分析堆記憶體和棧記憶體使用,甚至性能調優都有幫助。
查看預設值(Updated)
查看堆的預設值,使用下麵的代碼,其中InitialHeapSize為最開始的堆的大小,MaxHeapSize為堆的最大值。
1
2
3
4
5
6
7
8
9
|
|
查看棧的預設值,其中ThreadStackSize為棧記憶體的大小。
1
2
3
4
5
6
7
|
|