Java中堆和棧的概念和區(qū)別
當(dāng)一個(gè)人開(kāi)始學(xué)習(xí)Java或者其他編程語(yǔ)言的時(shí)候,會(huì)接觸到堆和棧,由于一開(kāi)始沒(méi)有明確清晰的說(shuō)明解釋,很多人會(huì)產(chǎn)生很多疑問(wèn),什么是堆,什么是棧,堆和棧有什么區(qū)別?更糟糕的是,Java中存在棧這樣一個(gè)后進(jìn)先出(Last In First Out)的順序的數(shù)據(jù)結(jié)構(gòu),這就是java.util.Stack。這種情況下,不免讓很多人更加費(fèi)解前面的問(wèn)題。事實(shí)上,堆和棧都是內(nèi)存中的一部分,有著不同的作用,而且一個(gè)程序需要在這片區(qū)域上分配內(nèi)存。眾所周知,所有的Java程序都運(yùn)行在JVM虛擬機(jī)內(nèi)部,我們這里介紹的自然是JVM(虛擬)內(nèi)存中的堆和棧。
堆1. Java的堆是一個(gè)運(yùn)行時(shí)數(shù)據(jù)區(qū),類(lèi)的對(duì)象從堆中分配空間。這些對(duì)象通過(guò)new等指令建立,通過(guò)垃圾回收器來(lái)銷(xiāo)毀。2. 堆的優(yōu)勢(shì)是可以動(dòng)態(tài)地分配內(nèi)存空間,需要多少內(nèi)存空間不必事先告訴編譯器,因?yàn)樗窃谶\(yùn)行時(shí)動(dòng)態(tài)分配的。但缺點(diǎn)是,由于需要在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存,所以存取速度較慢。
棧1. 棧中主要存放一些基本數(shù)據(jù)類(lèi)型的變量(byte,short,int,long,float,double,boolean,char)和對(duì)象的引用。2. 棧的優(yōu)勢(shì)是,存取速度比堆快,棧數(shù)據(jù)可以共享。但缺點(diǎn)是,存放在棧中的數(shù)據(jù)占用多少內(nèi)存空間需要在編譯時(shí)確定下來(lái),缺乏靈活性。
舉例說(shuō)明棧數(shù)據(jù)可以共享
String 可以用以下兩種方式來(lái)創(chuàng)建:
第一種使用new來(lái)創(chuàng)建的對(duì)象,它存放在堆中。每調(diào)用一次就創(chuàng)建一個(gè)新的對(duì)象。
第二種是先在棧中創(chuàng)建對(duì)象的引用str2,然后查找棧中有沒(méi)有存放“abc”,如果沒(méi)有,則將“abc”存放進(jìn)棧,并將str2指向“abc”,如果已經(jīng)有“abc”, 則直接將str2指向“abc”。
下面用代碼說(shuō)明上面的理論:
public static void main(String[] args) {String str1 = new String('abc');String str2 = new String('abc');System.out.println(str1 == str2); }
輸出結(jié)果為:false
public static void main(String[] args) {String str1 = 'abc';String str2 = 'abc';System.out.println(str1 == str2); }
輸出結(jié)果為:true
因此,用第二種方式創(chuàng)建多個(gè)“abc”字符串,在內(nèi)存中其實(shí)只存在一個(gè)對(duì)象而已。這種寫(xiě)法有利于節(jié)省內(nèi)存空間。同時(shí)還可以提高程序的運(yùn)行速度,因?yàn)镴VM會(huì)自動(dòng)根據(jù)棧中數(shù)據(jù)的實(shí)際情況來(lái)決定是否創(chuàng)建新對(duì)象。
String str1 = new String('abc');String str2 = 'abc';
附錄:Java中的堆和棧的區(qū)別
java中堆和棧的區(qū)別自然是面試中的常見(jiàn)問(wèn)題,下面幾點(diǎn)就是其具體的區(qū)別
各司其職
最主要的區(qū)別就是棧內(nèi)存用來(lái)存儲(chǔ)局部變量和方法調(diào)用。而堆內(nèi)存用來(lái)存儲(chǔ)Java中的對(duì)象。無(wú)論是成員變量,局部變量,還是類(lèi)變量,它們指向的對(duì)象都存儲(chǔ)在堆內(nèi)存中。
獨(dú)有還是共享
棧內(nèi)存歸屬于單個(gè)線程,每個(gè)線程都會(huì)有一個(gè)棧內(nèi)存,其存儲(chǔ)的變量只能在其所屬線程中可見(jiàn),即棧內(nèi)存可以理解成線程的私有內(nèi)存。而堆內(nèi)存中的對(duì)象對(duì)所有線程可見(jiàn)。堆內(nèi)存中的對(duì)象可以被所有線程訪問(wèn)。
異常錯(cuò)誤
如果棧內(nèi)存沒(méi)有可用的空間存儲(chǔ)方法調(diào)用和局部變量,JVM會(huì)拋出java.lang.StackOverFlowError。而如果是堆內(nèi)存沒(méi)有可用的空間存儲(chǔ)生成的對(duì)象,JVM會(huì)拋出java.lang.OutOfMemoryError。
空間大小
棧的內(nèi)存要遠(yuǎn)遠(yuǎn)小于堆內(nèi)存,如果你使用遞歸的話,那么你的棧很快就會(huì)充滿。如果遞歸沒(méi)有及時(shí)跳出,很可能發(fā)生StackOverFlowError問(wèn)題。你可以通過(guò)-Xss選項(xiàng)設(shè)置棧內(nèi)存的大小。-Xms選項(xiàng)可以設(shè)置堆的開(kāi)始時(shí)的大小,-Xmx選項(xiàng)可以設(shè)置堆的最大值。
這就是Java中堆和棧的區(qū)別。理解好這個(gè)問(wèn)題的話,可以對(duì)你解決開(kāi)發(fā)中的問(wèn)題,分析堆內(nèi)存和棧內(nèi)存使用,甚至性能調(diào)優(yōu)都有幫助。
查看默認(rèn)值(Updated)
查看堆的默認(rèn)值,使用下面的代碼,其中InitialHeapSize為最開(kāi)始的堆的大小,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)
總結(jié)
到此這篇關(guān)于Java中堆和棧的概念和區(qū)別的文章就介紹到這了,更多相關(guān)java 堆和棧的概念和區(qū)別內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!
相關(guān)文章:
1. Python文本文件的合并操作方法代碼實(shí)例2. windows服務(wù)器使用IIS時(shí)thinkphp搜索中文無(wú)效問(wèn)題3. asp讀取xml文件和記數(shù)4. Python sorted排序方法如何實(shí)現(xiàn)5. ASP.NET MVC實(shí)現(xiàn)橫向展示購(gòu)物車(chē)6. 每日六道java新手入門(mén)面試題,通往自由的道路第二天7. Python 中如何使用 virtualenv 管理虛擬環(huán)境8. python利用opencv實(shí)現(xiàn)顏色檢測(cè)9. CSS自定義滾動(dòng)條樣式案例詳解10. PHP實(shí)現(xiàn)基本留言板功能原理與步驟詳解
