Java中堆和棧的區(qū)別詳解
當(dāng)一個人開始學(xué)習(xí)Java或者其他編程語言的時候,會接觸到堆和棧,由于一開始沒有明確清晰的說明解釋,很多人會產(chǎn)生很多疑問,什么是堆,什么是棧,堆和棧有什么區(qū)別?更糟糕的是,Java中存在棧這樣一個后進(jìn)先出(Last In First Out)的順序的數(shù)據(jù)結(jié)構(gòu),這就是java.util.Stack。這種情況下,不免讓很多人更加費解前面的問題。事實上,堆和棧都是內(nèi)存中的一部分,有著不同的作用,而且一個程序需要在這片區(qū)域上分配內(nèi)存。眾所周知,所有的Java程序都運行在JVM虛擬機(jī)內(nèi)部,我們這里介紹的自然是JVM(虛擬)內(nèi)存中的堆和棧。
區(qū)別
java中堆和棧的區(qū)別自然是面試中的常見問題,下面幾點就是其具體的區(qū)別
各司其職
最主要的區(qū)別就是棧內(nèi)存用來存儲局部變量和方法調(diào)用。
而堆內(nèi)存用來存儲Java中的對象。無論是成員變量,局部變量,還是類變量,它們指向的對象都存儲在堆內(nèi)存中。
獨有還是共享
棧內(nèi)存歸屬于單個線程,每個線程都會有一個棧內(nèi)存,其存儲的變量只能在其所屬線程中可見,即棧內(nèi)存可以理解成線程的私有內(nèi)存。
而堆內(nèi)存中的對象對所有線程可見。堆內(nèi)存中的對象可以被所有線程訪問。
異常錯誤
如果棧內(nèi)存沒有可用的空間存儲方法調(diào)用和局部變量,JVM會拋出java.lang.StackOverFlowError。
而如果是堆內(nèi)存沒有可用的空間存儲生成的對象,JVM會拋出java.lang.OutOfMemoryError。
空間大小
棧的內(nèi)存要遠(yuǎn)遠(yuǎn)小于堆內(nèi)存,如果你使用遞歸的話,那么你的棧很快就會充滿。如果遞歸沒有及時跳出,很可能發(fā)生StackOverFlowError問題。
你可以通過-Xss選項設(shè)置棧內(nèi)存的大小。-Xms選項可以設(shè)置堆的開始時的大小,-Xmx選項可以設(shè)置堆的最大值。
這就是Java中堆和棧的區(qū)別。理解好這個問題的話,可以對你解決開發(fā)中的問題,分析堆內(nèi)存和棧內(nèi)存使用,甚至性能調(diào)優(yōu)都有幫助。
查看默認(rèn)值(Updated)
查看堆的默認(rèn)值,使用下面的代碼,其中InitialHeapSize為最開始的堆的大小,MaxHeapSize為堆的最大值。
13:17 $ java -XX:+PrintFlagsFinal -version | grep HeapSize
uintx ErgoHeapSizeLimit = 0 {product}
uintx HeapSizePerGCThread = 87241520 {product}
uintx InitialHeapSize := 134217728 {product}
uintx LargePageHeapSizeThreshold = 134217728 {product}
uintx MaxHeapSize := 2147483648 {product}
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
查看棧的默認(rèn)值,其中ThreadStackSize為棧內(nèi)存的大小。
13:21 $ java -XX:+PrintFlagsFinal -version | grep ThreadStackSize
intx CompilerThreadStackSize = 0 {pd product}
intx ThreadStackSize = 1024 {pd product}
intx VMThreadStackSize = 1024 {pd product}
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
譯文信息
原汁原味的英文原文:http://javarevisited.blogspot.com.au/2013/01/difference-between-stack-and-heap-java.html.
譯文在原文基礎(chǔ)上進(jìn)行了修改,整理,刪減。如有興趣可以訪問原文。P.S.地址已被墻。
相關(guān)文章
并發(fā)編程之Java內(nèi)存模型鎖的內(nèi)存語義
這篇文章主要介紹了并發(fā)編程之Java內(nèi)存模型鎖的內(nèi)存語義,鎖的作用是讓臨界區(qū)互斥執(zhí)行,本文只要圍繞鎖的內(nèi)存語義展開全文內(nèi)容,需要的小伙伴可以參考一下2021-11-11
在Java的MyBatis框架中建立接口進(jìn)行CRUD操作的方法
這篇文章主要介紹了在Java的MyBatis框架中建立接口進(jìn)行CRUD操作的方法,CRUD是指在做計算處理時的增加(Create)、重新取得數(shù)據(jù)(Retrieve)、更新(Update)和刪除(Delete)幾個單詞的首字母簡寫,需要的朋友可以參考下2016-04-04
SpringBoot + SpringSecurity 短信驗證碼登錄功能實現(xiàn)
這篇文章主要介紹了SpringBoot + SpringSecurity 短信驗證碼登錄功能實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-06-06
Java框架Quartz中API、Jobs和Trigger詳解
這篇文章主要介紹了Java框架Quartz中API、Jobs和Trigger詳解,JobDetail?對象是在將?job?加入?scheduler?時,由客戶端程序(你的程序)創(chuàng)建的,它包含?job?的各種屬性設(shè)置,以及用于存儲?job?實例狀態(tài)信息的?JobDataMap,需要的朋友可以參考下2023-11-11

