其實(shí)我們都知道,計(jì)算機(jī)內(nèi)存本來就是一塊內(nèi)存,沒有堆棧之分。
在學(xué)編程的時(shí)候,我們應(yīng)該都聽過一句話 “如果程序結(jié)束之后仍然想要訪問那一段數(shù)據(jù)就要用堆”,我想這個(gè)其實(shí)就是你疑問的關(guān)鍵了,堆和棧都有其自己的獨(dú)特性,可能你了解這兩個(gè)東西,但是我還是解釋下,以免別的小伙伴在看答案的時(shí)候,不知道。
棧:就像我第一句話說的,本沒有什么堆棧之分,但是編程語言的出現(xiàn),就有了一個(gè)概念“函數(shù)”,這個(gè)函數(shù)之間是可以相互調(diào)用的(就像我們傳遞東西,比如:胡小然 將東西傳遞 胡小然2 將東西傳遞 胡小然3,之后需要從后面向前面反饋傳遞結(jié)果,這個(gè)傳遞的過程我們就可以理解為調(diào)用),那就出現(xiàn)了前后之分,這就是調(diào)用隊(duì)列了,那這個(gè)隊(duì)列有個(gè)什么特點(diǎn)呢,那就是先被調(diào)用進(jìn)入隊(duì)列的要最后出去,就是我們常說的先進(jìn)后出(FILO),那么這時(shí)棧就出現(xiàn)了,而且它還有一個(gè)特點(diǎn)那就是線程獨(dú)有(所以可以存放我們的臨時(shí)變量),生命周期是隨線程的。當(dāng)然我所說的是內(nèi)存棧的意思,其實(shí)“?!本褪莻€(gè)數(shù)據(jù)結(jié)構(gòu),是一種限定僅在表尾進(jìn)行插入和刪除操作的線性表,這個(gè)特性不正好是符合我剛才說的FILO嘛。所以你可以這么理解c++或者java(jvm)中的內(nèi)存棧的概念,就是編程語言的作者為了管理內(nèi)存使用了“?!边@種數(shù)據(jù)結(jié)構(gòu)(說的再細(xì)點(diǎn)就是現(xiàn)代CPU體系結(jié)構(gòu)決定了棧是管理函數(shù)調(diào)用和局部變量的最佳數(shù)據(jù)結(jié)構(gòu)。因?yàn)镃PU已經(jīng)提供了現(xiàn)成的指令)。
堆:可算是一種特殊的數(shù)據(jù)結(jié)構(gòu),好像我們經(jīng)常使用的二叉樹。內(nèi)存堆這個(gè)解釋起來就更簡(jiǎn)單了,就是一塊能自由分配的內(nèi)存。它允許程序在運(yùn)行時(shí)動(dòng)態(tài)地申請(qǐng)某個(gè)大小的內(nèi)存空間,比如:程序員向操作系統(tǒng)申請(qǐng)一塊內(nèi)存,當(dāng)系統(tǒng)收到程序的申請(qǐng)時(shí),會(huì)遍歷一個(gè)記錄空閑內(nèi)存地址的鏈表,尋找第一個(gè)空間大于所申請(qǐng)空間的堆結(jié)點(diǎn),然后將該結(jié)點(diǎn)從空閑結(jié)點(diǎn)鏈表中刪除,并將該結(jié)點(diǎn)的空間分配給程序。其特點(diǎn)就是分配的速度較慢,地址不連續(xù),容易碎片化并且是由程序員申請(qǐng),同時(shí)也必須由程序員負(fù)責(zé)銷毀,否則導(dǎo)致內(nèi)存泄露。像在java這種高級(jí)語言中,我們不比擔(dān)心內(nèi)存回收的問題,那是因?yàn)閖vm已經(jīng)在幫我們處理了。
上面說了這么多,就是想說明一下內(nèi)存棧和內(nèi)存堆出現(xiàn)的意義和作用,所以答案就出來了,那就是不能“只用堆或者全部只用?!蹦菢游覀兂绦虻恼{(diào)用和數(shù)據(jù)的存儲(chǔ)都會(huì)出現(xiàn)問題。
好了,上面只是我自己一些理解,不對(duì)的地方還請(qǐng)大家指出,也希望對(duì)題主的疑問有幫助。