Java是一門一直都很活躍在我們生活中的一門開發(fā)語言了,不管是多少年過去,也不管是有多少的開發(fā)語言的崛起都不能夠代替的了java在程序員心中的地位,java涉及的范圍是非常廣泛的,而且在技術(shù)上也是比較成熟的,那么java開發(fā)中堆和棧有什么區(qū)別呢?
堆和棧的區(qū)別:
各司其職,主要的區(qū)別就是棧內(nèi)存用來存儲(chǔ)局部變量和方法調(diào)用。而堆內(nèi)存用來存儲(chǔ)Java中的對(duì)象。無論是成員變量,局部變量,還是類變量,它們指向的對(duì)象都存儲(chǔ)在堆內(nèi)存中。
獨(dú)有還是共享,棧內(nèi)存歸屬于單個(gè)線程,每個(gè)線程都會(huì)有一個(gè)棧內(nèi)存,其存儲(chǔ)的變量只能在其所屬線程中可見,即棧內(nèi)存可以理解成線程的私有內(nèi)存。而堆內(nèi)存中的對(duì)象對(duì)所有線程可見。堆內(nèi)存中的對(duì)象可以被所有線程訪問。
異常錯(cuò)誤:如果棧內(nèi)存沒有可用的空間存儲(chǔ)方法調(diào)用和局部變量,JVM會(huì)拋出而如果是堆內(nèi)存沒有可用的空間存儲(chǔ)生成的對(duì)象,JVM會(huì)拋出java.lang.OutOfMemoryError。
空間大?。簵5膬?nèi)存要遠(yuǎn)遠(yuǎn)小于堆內(nèi)存,如果你使用遞歸的話,那么你的棧很快就會(huì)充滿。如果遞歸沒有及時(shí)跳出,很可能發(fā)生StackOverFlowError問題。你可以通過-Xss選項(xiàng)設(shè)置棧內(nèi)存的大小。-Xms選項(xiàng)可以設(shè)置堆的開始時(shí)的大小,-Xmx選項(xiàng)可以設(shè)置堆的值。
具體而言,棧內(nèi)存主要用來存放基本數(shù)據(jù)類型與引用變量,棧內(nèi)存的管理是通過壓棧和彈棧操作來完成的,以棧幀為基本單位來管理程序的調(diào)用關(guān)系,每當(dāng)有函數(shù)調(diào)用時(shí),都會(huì)通過壓棧方式創(chuàng)建新的棧幀,每當(dāng)函數(shù)調(diào)用結(jié)束后都會(huì)通過彈棧的方式釋放棧幀。
堆內(nèi)存用來存放運(yùn)行時(shí)創(chuàng)建的對(duì)象,一般來講,通過new關(guān)鍵字創(chuàng)建出來的對(duì)象都存放在堆內(nèi)存中,由于JVM是基于堆棧的虛擬機(jī),而每個(gè)java程序都運(yùn)行在一個(gè)單獨(dú)的jvm實(shí)列上,每一個(gè)實(shí)列對(duì)應(yīng)一個(gè)堆,一個(gè)java程序內(nèi)的多個(gè)線程也就運(yùn)行在同一個(gè)jvm實(shí)列上,因此這些線程之間會(huì)共享堆內(nèi)存,鑒于此,多線程在訪問堆中的數(shù)據(jù)時(shí)需要對(duì)數(shù)據(jù)進(jìn)行同步,
在C++中,堆內(nèi)存的管理都是由開發(fā)人員來負(fù)責(zé)的,也就是說,開發(fā)人員在堆中申請(qǐng)的內(nèi)存,當(dāng)不在使用時(shí),必須由開發(fā)人員完成堆內(nèi)存的釋放工作,而在java語言中,這個(gè)內(nèi)存釋放的工作由垃圾回收器來負(fù)責(zé)執(zhí)行,開發(fā)人員只需要申請(qǐng)所需的堆空間而不需要考慮釋放的問題。
在堆中產(chǎn)生了一個(gè)數(shù)組或?qū)ο蠛?,還可以在棧中定義一個(gè)特殊的變量,讓棧中這個(gè)變量的取值等于數(shù)組或?qū)ο笤诙褍?nèi)存中的首地址,棧中的這個(gè)變量就成了數(shù)組或?qū)ο蟮囊米兞?,引用變量就相?dāng)于是為數(shù)組或?qū)ο笃鸬囊粋€(gè)名稱,以后就可以在程序中使用棧中的引用變量來訪問堆中的數(shù)組或?qū)ο螅@就是java中引用的用法。
關(guān)于java開發(fā)中的堆和棧有什么區(qū)別達(dá)內(nèi)科技已經(jīng)和大家說了,如果說你想要了解或者是學(xué)習(xí)更多關(guān)于java的知識(shí)的話那么達(dá)內(nèi)科技?xì)g迎大家來我們公司的java培訓(xùn)班進(jìn)行實(shí)地考察,也可以點(diǎn)擊我們文章下面的獲取試聽資格按鈕來獲取我們的java課程免費(fèi)試聽資格,在試聽中可以更加深入的了解達(dá)內(nèi)科技。