0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一文看懂堆和棧的區(qū)別和聯(lián)系

姚小熊27 ? 來源:網(wǎng)絡(luò)整理 ? 2018-04-11 09:50 ? 次閱讀

堆和棧概要

在計算機(jī)領(lǐng)域,堆棧是一個不容忽視的概念,堆棧是兩種數(shù)據(jù)結(jié)構(gòu)。堆棧都是一種數(shù)據(jù)項(xiàng)按序排列的數(shù)據(jù)結(jié)構(gòu),只能在一端(稱為棧頂(top))對數(shù)據(jù)項(xiàng)進(jìn)行插入和刪除。在單片機(jī)應(yīng)用中,堆棧是個特殊的存儲區(qū),主要功能是暫時存放數(shù)據(jù)和地址,通常用來保護(hù)斷點(diǎn)和現(xiàn)場。

堆和棧的要點(diǎn)

堆,隊(duì)列優(yōu)先,先進(jìn)先出(FIFO—firstinfirstout)。

棧,先進(jìn)后出(FILO—First-In/Last-Out)。

一般情況下,如果有人把堆棧合起來說,那它的意思是棧,可不是堆。

一文看懂堆和棧的區(qū)別和聯(lián)系

堆和棧的對比分析

1、堆??臻g分配

棧(操作系統(tǒng)):由操作系統(tǒng)自動分配釋放,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。

堆(操作系統(tǒng)):一般由程序員分配釋放,若程序員不釋放,程序結(jié)束時可能由OS回收,分配方式倒是類似于鏈表

2、堆棧緩存方式

棧使用的是一級緩存,他們通常都是被調(diào)用時處于存儲空間中,調(diào)用完畢立即釋放。

堆則是存放在二級緩存中,生命周期由虛擬機(jī)的垃圾回收算法來決定(并不是一旦成為孤兒對象就能被回收)。所以調(diào)用這些對象的速度要相對來得低一些。

3、堆棧數(shù)據(jù)結(jié)構(gòu)區(qū)別

堆(數(shù)據(jù)結(jié)構(gòu)):堆可以被看成是一棵樹,如:堆排序。

棧(數(shù)據(jù)結(jié)構(gòu)):一種先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu)。

一文看懂堆和棧的區(qū)別和聯(lián)系

堆和棧的聯(lián)系

主函數(shù)先進(jìn)棧,在棧中定義一個變量arr,接下來為arr賦值,但是右邊不是一個具體值,是一個實(shí)體。實(shí)體創(chuàng)建在堆里,在堆里首先通過new關(guān)鍵字開辟一個空間,內(nèi)存在存儲數(shù)據(jù)的時候都是通過地址來體現(xiàn)的,地址是一塊連續(xù)的二進(jìn)制,然后給這個實(shí)體分配一個內(nèi)存地址。數(shù)組都是有一個索引,數(shù)組這個實(shí)體在堆內(nèi)存中產(chǎn)生之后每一個空間都會進(jìn)行默認(rèn)的初始化(這是堆內(nèi)存的特點(diǎn),未初始化的數(shù)據(jù)是不能用的,但在堆里是可以用的,因?yàn)槌跏蓟^了,但是在棧里沒有),不同的類型初始化的值不一樣。所以堆和棧里就創(chuàng)建了變量和實(shí)體:

一文看懂堆和棧的區(qū)別和聯(lián)系

給堆分配了一個地址,把堆的地址賦給arr,arr就通過地址指向了數(shù)組。所以arr想操縱數(shù)組時,就通過地址,而不是直接把實(shí)體都賦給它。這種我們不再叫他基本數(shù)據(jù)類型,而叫引用數(shù)據(jù)類型。稱為arr引用了堆內(nèi)存當(dāng)中的實(shí)體。(可以理解為c或c++的指針,Java成長自c++和c++很像,優(yōu)化了c++)

如果當(dāng)int[]arr=null;

arr不做任何指向,null的作用就是取消引用數(shù)據(jù)類型的指向。

當(dāng)一個實(shí)體,沒有引用數(shù)據(jù)類型指向的時候,它在堆內(nèi)存中不會被釋放,而被當(dāng)做一個垃圾,在不定時的時間內(nèi)自動回收,因?yàn)镴ava有一個自動回收機(jī)制,(而c++沒有,需要程序員手動回收,如果不回收就越堆越多,直到撐滿內(nèi)存溢出,所以Java在內(nèi)存管理上優(yōu)于c++)。自動回收機(jī)制(程序)自動監(jiān)測堆里是否有垃圾,如果有,就會自動的做垃圾回收的動作,但是什么時候收不一定。

所以堆與棧的區(qū)別很明顯:

1.棧內(nèi)存存儲的是局部變量而堆內(nèi)存存儲的是實(shí)體;

2.棧內(nèi)存的更新速度要快于堆內(nèi)存,因?yàn)榫植孔兞康纳芷诤芏蹋?/p>

3.棧內(nèi)存存放的變量生命周期一旦結(jié)束就會被釋放,而堆內(nèi)存存放的實(shí)體會被垃圾回收機(jī)制不定時的回收。

堆與棧的主要區(qū)別

1、管理方式:對于棧來講,是由編譯器自動管理,無需我們手工控制;對于堆來說,釋放工作由程序員控制,容易產(chǎn)生memoryleak。

2、空間大小:一般來講在32位系統(tǒng)下,堆內(nèi)存可以達(dá)到4G的空間,從這個角度來看堆內(nèi)存幾乎是沒有什么限制的。但是對于棧來講,一般都是有一定的空間大小的,例如,在VC6下面,默認(rèn)的??臻g大小是1M(好像是,記不清楚了)。當(dāng)然,我們可以修改:

3、打開工程,依次操作菜單如下:Project-》Setting-》Link,在Category中選中Output,然后在Reserve中設(shè)定堆棧的最大值和commit。

注意:reserve最小值為4Byte;commit是保留在虛擬內(nèi)存的頁文件里面,它設(shè)置的較大會使棧開辟較大的值,可能增加內(nèi)存的開銷和啟動時間。

4、碎片問題:對于堆來講,頻繁的new/delete勢必會造成內(nèi)存空間的不連續(xù),從而造成大量的碎片,使程序效率降低。對于棧來講,則不會存在這個問題,因?yàn)闂J窍冗M(jìn)后出的隊(duì)列,他們是如此的一一對應(yīng),以至于永遠(yuǎn)都不可能有一個內(nèi)存塊從棧中間彈出,在他彈出之前,在他上面的后進(jìn)的棧內(nèi)容已經(jīng)被彈出,詳細(xì)的可以參考數(shù)據(jù)結(jié)構(gòu),這里我們就不再一一討論了。

5、生長方向:對于堆來講,生長方向是向上的,也就是向著內(nèi)存地址增加的方向;對于棧來講,它的生長方向是向下的,是向著內(nèi)存地址減小的方向增長。

6、分配方式:堆都是動態(tài)分配的,沒有靜態(tài)分配的堆。棧有2種分配方式:靜態(tài)分配和動態(tài)分配。靜態(tài)分配是編譯器完成的,比如局部變量的分配。動態(tài)分配由alloca函數(shù)進(jìn)行分配,但是棧的動態(tài)分配和堆是不同的,他的動態(tài)分配是由編譯器進(jìn)行釋放,無需我們手工實(shí)現(xiàn)。

7、分配效率:棧是機(jī)器系統(tǒng)提供的數(shù)據(jù)結(jié)構(gòu),計算機(jī)會在底層對棧提供支持:分配專門的寄存器存放棧的地址,壓棧出棧都有專門的指令執(zhí)行,這就決定了棧的效率比較高。堆則是C/C++函數(shù)庫提供的,它的機(jī)制是很復(fù)雜的,例如為了分配一塊內(nèi)存,庫函數(shù)會按照一定的算法(具體的算法可以參考數(shù)據(jù)結(jié)構(gòu)/操作系統(tǒng))在堆內(nèi)存中搜索可用的足夠大小的空間,如果沒有足夠大小的空間(可能是由于內(nèi)存碎片太多),就有可能調(diào)用系統(tǒng)功能去增加程序數(shù)據(jù)段的內(nèi)存空間,這樣就有機(jī)會分到足夠大小的內(nèi)存,然后進(jìn)行返回。顯然,堆的效率比棧要低得多。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
收藏 人收藏

    評論

    相關(guān)推薦

    區(qū)別在哪

    以下引用網(wǎng)上資料 理解區(qū)別(1)區(qū)(stack):由編譯器自動分配和釋放,存放函數(shù)的參數(shù)值、局部變量的值等,其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的
    發(fā)表于 08-11 09:18

    C語言單片機(jī)、、堆棧的區(qū)別是什么?

    C語言單片機(jī)、堆棧的區(qū)別是什么?
    發(fā)表于 10-13 08:09

    單片機(jī)中有什么區(qū)別

    M0中的、空間的區(qū)別:(1)區(qū)(st
    發(fā)表于 11-22 06:23

    STM32中的區(qū)別是什么

    區(qū)別是什么?的空間是如何進(jìn)行分配的?
    發(fā)表于 11-29 07:05

    區(qū)別是什么

    在回答完進(jìn)程的虛擬地址空間布局之后(上篇),面試官可能抓住深入展開。區(qū)別①管理方
    發(fā)表于 12-22 07:26

    什么是?什么是

    在嵌入式編程中,個很重要的概念,不管是裸機(jī)編程還是基于RTOS編程。函數(shù)形參、局部變量、函數(shù)調(diào)用現(xiàn)場的保護(hù)及返回地址、中斷函數(shù)執(zhí)行前線程保護(hù)及中斷嵌套的現(xiàn)場的保護(hù)都依賴于空間。
    發(fā)表于 12-22 06:09

    單片機(jī)區(qū)別在哪

    文末有圖和程序幫助理解!?。?b class='flag-5'>堆區(qū)別可以用如下的比喻來看出:使用就象我們?nèi)ワ堭^里吃飯,只管點(diǎn)菜(發(fā)出申請)、付錢、和吃(使用),吃飽了就走不必理會切菜、洗菜等準(zhǔn)備工作和洗碗、刷鍋
    發(fā)表于 01-20 08:31

    明確區(qū)分,究竟有什么區(qū)別?

    這條短短的句話就包含了,看到new,我們首先就應(yīng)該想到,我們分配了內(nèi)存,那么指針p呢?他分配的是
    的頭像 發(fā)表于 04-09 09:45 ?4317次閱讀
    明確區(qū)分<b class='flag-5'>堆</b>與<b class='flag-5'>棧</b>,<b class='flag-5'>堆</b>和<b class='flag-5'>棧</b>究竟有什么<b class='flag-5'>區(qū)別</b>?

    如何分清區(qū)別(7大關(guān)鍵點(diǎn))

    區(qū)別直都是永恒的話題,為此我也查了很多的資料,以防自己的理解錯誤,而給他人造成理解偏差。
    發(fā)表于 12-24 10:47 ?1.1w次閱讀

    C語言內(nèi)存的筆記資料說明

    本文檔的主要內(nèi)容詳細(xì)介紹的是C語言內(nèi)存的筆記資料說明說明了C語言中區(qū)別,哪些數(shù)據(jù)存放在
    發(fā)表于 02-14 08:00 ?3次下載
    C語言內(nèi)存<b class='flag-5'>堆</b>與<b class='flag-5'>棧</b>的筆記資料說明

    理解區(qū)別(STM32)資料下載

    電子發(fā)燒友網(wǎng)為你提供理解區(qū)別(STM32)資料下載的電子資料下載,更有其他相關(guān)的電路圖、源代碼、課件教程、中文資料、英文資料、參考設(shè)計、用戶指南、解決方案等資料,希望可以幫助到廣大的電子工程師們。
    發(fā)表于 03-31 08:44 ?14次下載
    理解<b class='flag-5'>堆</b>和<b class='flag-5'>棧</b>的<b class='flag-5'>區(qū)別</b>(STM32)資料下載

    單片機(jī)中區(qū)別

    M0中的、空間的區(qū)別:(1)區(qū)(st
    發(fā)表于 11-13 14:51 ?9次下載
    單片機(jī)中<b class='flag-5'>堆</b>和<b class='flag-5'>棧</b>的<b class='flag-5'>區(qū)別</b>

    的增長方向?yàn)槭裁赐ǔJ窍喾吹模?/a>

    數(shù)據(jù)結(jié)構(gòu)中,(heap)與(stack)是兩個常見的數(shù)據(jù)結(jié)構(gòu),它們的存在都是為了優(yōu)化內(nèi)存,提高使用效率,各有特點(diǎn),理解二者的定義、用法與區(qū)別,能夠利用
    的頭像 發(fā)表于 02-15 15:08 ?7756次閱讀
    <b class='flag-5'>堆</b>和<b class='flag-5'>棧</b>的增長方向?yàn)槭裁赐ǔJ窍喾吹模? />    </a>
</div>                            <div   id=

    嵌入式C語言中區(qū)別

    在嵌入式C語言中,都是用來存儲變量的內(nèi)存區(qū)域,但它們在存儲和使用變量方面有很大的區(qū)別。
    的頭像 發(fā)表于 04-14 11:45 ?1206次閱讀

    區(qū)別和使用注意事項(xiàng)

    是在計算機(jī)科學(xué)中廣泛使用的兩種數(shù)據(jù)結(jié)構(gòu),它們具有不同的用途和特點(diǎn)。區(qū)別涉及到內(nèi)存分配、訪問方式、數(shù)據(jù)存儲等方面。在使用
    的頭像 發(fā)表于 01-18 17:24 ?1555次閱讀