棧內(nèi)存和堆內(nèi)存的一點(diǎn)小結(jié)

棧內(nèi)存和堆內(nèi)存

  • 形象化的理解:
    Object obj = new Object();
    ??以上這句話,會(huì)把obj這個(gè)引用放進(jìn)棧內(nèi)存,再說(shuō)白一點(diǎn),就是這個(gè)對(duì)象的名字obj放進(jìn)棧內(nèi)存,棧內(nèi)存運(yùn)行速度較快,用于查找索引(也就是名字)
    ??而new Object()會(huì)在堆內(nèi)存中開(kāi)辟一塊空間給這個(gè)對(duì)象,對(duì)象幾乎所有的屬性啊,方法啊,全都在里面了,也就是對(duì)象的實(shí)體都在堆內(nèi)存中,堆內(nèi)存速度慢但是成本低,空間較大,用以存放程序
  • 具體分析
    • 內(nèi)存分配策略
      ??按照編譯原理的觀點(diǎn),程序運(yùn)行時(shí)的內(nèi)存分配有三種策略,分別是靜態(tài)的,棧式的,和堆式的。如下:
      ??靜態(tài)存儲(chǔ)分配是指在編譯時(shí)就能確定每個(gè)數(shù)據(jù)目標(biāo)在運(yùn)行時(shí)刻的存儲(chǔ)空間需求,因而在編譯時(shí)就可以給他們分配固定的內(nèi)存空間.這種分配策略要求程序代碼中不允許有可變數(shù)據(jù)結(jié)構(gòu)(比如可變數(shù)組)的存在,也不允許有嵌套或者遞歸的結(jié)構(gòu)出現(xiàn),因?yàn)樗鼈兌紩?huì)導(dǎo)致編譯程序無(wú)法計(jì)算準(zhǔn)確的存儲(chǔ)空間需求。
      ??棧式存儲(chǔ)分配也可稱為動(dòng)態(tài)存儲(chǔ)分配,是由一個(gè)類似于堆棧的運(yùn)行棧來(lái)實(shí)現(xiàn)的.和靜態(tài)存儲(chǔ)分配相反,在棧式存儲(chǔ)方案中,程序?qū)?shù)據(jù)區(qū)的需求在編譯時(shí)是完全未知的,只有到運(yùn)行的時(shí)候才能夠知道,但是規(guī)定在運(yùn)行中進(jìn)入一個(gè)程序模塊時(shí),必須知道該程序模塊所需的數(shù)據(jù)區(qū)大小才能夠?yàn)槠浞峙鋬?nèi)存.和我們?cè)跀?shù)據(jù)結(jié)構(gòu)所熟知的棧一樣,棧式存儲(chǔ)分配按照先進(jìn)后出的原則進(jìn)行分配。
      ??堆式存儲(chǔ)(Heap)分配則專門(mén)負(fù)責(zé)在編譯時(shí)或運(yùn)行時(shí)模塊入口處都無(wú)法確定存儲(chǔ)要求的數(shù)據(jù)結(jié)構(gòu)的內(nèi)存分配,比如可變長(zhǎng)度串和對(duì)象實(shí)例.堆由大片的可利用塊或空閑塊組成,堆中的內(nèi)存可以按照任意順序分配和釋放。
    • 舉例分析
      ??當(dāng)編譯一個(gè)C++程序時(shí),計(jì)算機(jī)的內(nèi)存被分成了4個(gè)區(qū)域,一個(gè)包括程序的代碼,一個(gè)包括所有的全局變量,一個(gè)是堆棧(Stack),還有一個(gè)是堆(Heap)
      ??全局變量是靜態(tài)存儲(chǔ)的(但不是靜態(tài)的,不能用static進(jìn)行修飾)。用static聲明局部變量“的目的是使局部變量在調(diào)用完函數(shù)后仍不釋放空間,而全局變量完全能做到這點(diǎn)。(當(dāng)然,能不用試最好不要去用全局變量,它會(huì)造成很多干擾)
      ??棧的概念是從日常生活中貨物在貨棧種的存取過(guò)程抽象出來(lái)的,即最后存放入棧的貨物(堆在靠出口處)先被提取出去,符合“先進(jìn)后出,后進(jìn)先出”的原則。這種結(jié)構(gòu)猶如子彈夾。
      ??堆是自由的內(nèi)存區(qū)域,我們可以通過(guò)new和delete把對(duì)象放在這個(gè)區(qū)域。你可以在任何地方分配和釋放自由存儲(chǔ)區(qū)。
    • 總結(jié)
      ??從堆和棧的功能和作用來(lái)通俗的比較,堆主要用來(lái)存放對(duì)象的,棧主要是用來(lái)執(zhí)行程序的.而這種不同又主要是由于堆和棧的特點(diǎn)決定的:
      ??在編程中,例如C/C++中,所有的方法調(diào)用都是通過(guò)棧來(lái)進(jìn)行的,所有的局部變量,形式參數(shù)都是從棧中分配內(nèi)存空間的。實(shí)際上也不是什么分配,只是從棧頂向上用就行,就好像工廠中的傳送帶(conveyor belt)一樣,Stack Pointer會(huì)自動(dòng)指引你到放東西的位置,你所要做的只是把東西放下來(lái)就行.退出函數(shù)的時(shí)候,修改棧指針就可以把棧中的內(nèi)容銷毀.這樣的模式速度最快,當(dāng)然要用來(lái)運(yùn)行程序了.需要注意的是,在分配的時(shí)候,比如為一個(gè)即將要調(diào)用的程序模塊分配數(shù)據(jù)區(qū)時(shí),應(yīng)事先知道這個(gè)數(shù)據(jù)區(qū)的大小,也就說(shuō)是雖然分配是在程序運(yùn)行時(shí)進(jìn)行的,但是分配的大小多少是確定的,不變的,而這個(gè)"大小多少"是在編譯時(shí)確定的,不是在運(yùn)行時(shí)。
      ??堆是應(yīng)用程序在運(yùn)行的時(shí)候請(qǐng)求操作系統(tǒng)分配給自己內(nèi)存,由于從操作系統(tǒng)管理的內(nèi)存分配,所以在分配和銷毀時(shí)都要占用時(shí)間,因此用堆的效率非常低.但是堆的優(yōu)點(diǎn)在于,編譯器不必知道要從堆里分配多少存儲(chǔ)空間,也不必知道存儲(chǔ)的數(shù)據(jù)要在堆里停留多長(zhǎng)的時(shí)間,因此,用堆保存數(shù)據(jù)時(shí)會(huì)得到更大的靈活性。事實(shí)上,面向?qū)ο蟮亩鄳B(tài)性,堆內(nèi)存分配是必不可少的,因?yàn)槎鄳B(tài)變量所需的存儲(chǔ)空間只有在運(yùn)行時(shí)創(chuàng)建了對(duì)象之后才能確定.在C++中,要求創(chuàng)建一個(gè)對(duì)象時(shí),只需用new命令編制相關(guān)的代碼即可。執(zhí)行這些代碼時(shí),會(huì)在堆里自動(dòng)進(jìn)行數(shù)據(jù)的保存.當(dāng)然,為達(dá)到這種靈活性,必然會(huì)付出一定的代價(jià):在堆里分配存儲(chǔ)空間時(shí)會(huì)花掉更長(zhǎng)的時(shí)間!這也正是導(dǎo)致我們剛才所說(shuō)的效率低的原因。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,803評(píng)論 11 349
  • 在函數(shù)中定義的一些基本類型的變量和對(duì)象的引用變量都在函數(shù)的棧內(nèi)存中分配。 當(dāng)在一段代碼塊定義一個(gè)變量時(shí),Java就...
    木有魚(yú)丸啦閱讀 632評(píng)論 0 0
  • Java把內(nèi)存分成兩種,一種叫做棧內(nèi)存,一種叫做堆內(nèi)存 在函數(shù)中定義的一些基本類型的變量和對(duì)象的引用變量都是在函數(shù)...
    keyu88888閱讀 1,340評(píng)論 3 47
  • 男友跟我,哦不,現(xiàn)在是前男友。前男友跟我都是安靜的人,不想交流的時(shí)候可以整天不說(shuō)一句話。也許是因?yàn)楦髯陨习嘤X(jué)得很辛...
    洪小花閱讀 295評(píng)論 0 0
  • 記者采訪作家李欣頻:“如果現(xiàn)在你有一億元,你會(huì)去做什么?”李欣頻說(shuō),好好笑哦,我想做一件事情的時(shí)候,從來(lái)不會(huì)考慮錢(qián)...
    鴨蛋不咸閱讀 2,984評(píng)論 1 1

友情鏈接更多精彩內(nèi)容