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

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

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

什么是堆內(nèi)存與棧內(nèi)存?它們的分配和回收有什么特點(diǎn)?

xCb1_yikoulinux ? 來源:程序喵大人 ? 作者:程序喵大人 ? 2022-07-01 10:33 ? 次閱讀

這篇文章分享一個面試中經(jīng)常被問到的知識點(diǎn):堆內(nèi)存和棧內(nèi)存有什么區(qū)別?平時開發(fā)應(yīng)該使用堆內(nèi)存還是棧內(nèi)存?

要回答這個問題,我們首先需要知道什么是堆內(nèi)存,什么是棧內(nèi)存,它們的分配和回收有什么特點(diǎn)?

先介紹下棧內(nèi)存:

棧內(nèi)存是為線程留出的臨時空間,每個線程都有一個固定大小的??臻g,而且??臻g存儲的數(shù)據(jù)只能由當(dāng)前線程訪問,所以它是線程安全的。

??臻g的分配和回收是由系統(tǒng)來做的,我們不需要手動控制。

當(dāng)一個函數(shù)調(diào)用時,系統(tǒng)就會為該函數(shù)的調(diào)用分配??臻g,當(dāng)函數(shù)返回后,系統(tǒng)就會自動回收這塊空間,同理,下次其它函數(shù)調(diào)用和返回,系統(tǒng)還是會自動分配和回收空間。

那它是怎么分配和回收的呢?

可以看這兩個動畫

9455e43c-f75f-11ec-ba43-dac502259ad0.gif

94ae6f6c-f75f-11ec-ba43-dac502259ad0.gif

??臻g的大小是固定的,它有一個水位線,標(biāo)識??臻g的分配狀態(tài),水位線里面的表示已經(jīng)分配,然后這個水位線會根據(jù)函數(shù)調(diào)用和返回的情況自動調(diào)整。

這里可以看到,??臻g的分配和回收非常簡單,只需要調(diào)整水位線位置就可以了,沒有任何多余操作。

那堆內(nèi)存呢?

我們平時在C語言C++中使用malloc和new分配的內(nèi)存就是堆內(nèi)存,堆內(nèi)存的一大特點(diǎn)就是大小不固定,可以動態(tài)擴(kuò)容,空間由程序員動態(tài)分配,更加靈活。

然而,既然有優(yōu)點(diǎn)也必然伴隨著缺點(diǎn)。

第一個缺點(diǎn)就是它容易產(chǎn)生內(nèi)存泄露,malloc出來的沒有free,new出來的如果沒有delete,都會產(chǎn)生內(nèi)存泄露,真正項(xiàng)目內(nèi)存泄露產(chǎn)生的情況肯定比這個復(fù)雜的多。

第二個缺點(diǎn),容易產(chǎn)生內(nèi)存碎片,在分配和回收時需要對很多內(nèi)存碎片進(jìn)行整理,效率較低,具體可以看這個動畫。

94c9bace-f75f-11ec-ba43-dac502259ad0.gif

所以才會有很多自定義的內(nèi)存分配器,但它肯定還是沒有??臻g分配回收速度快。

第三個缺點(diǎn),線程不安全,它不像棧內(nèi)存是線程獨(dú)立的,堆內(nèi)存可以被一個進(jìn)程內(nèi)所有的線程訪問,多線程操作就容易產(chǎn)生問題,很多奇奇怪怪的操作就是這么引起的。

那什么變量存儲在棧上,什么存儲在堆上呢?普通的A a,這種就是都存儲在棧上,當(dāng)使用new和malloc分配的空間會存儲在堆上,看這個圖:

94ebba7a-f75f-11ec-ba43-dac502259ad0.jpg

new出來的實(shí)際空間是在堆上分配,然后在棧上開辟一個指針大小的空間,這個空間有一個指針,指向堆上的那塊內(nèi)存,這樣給變量和堆內(nèi)存之間就關(guān)聯(lián)起來了。

那什么情況下使用棧內(nèi)存,什么情況下使用堆內(nèi)存呢?

我整理出來了一個表,貼在這里:

速度
空間管理 高效,不會產(chǎn)生碎片 會產(chǎn)生內(nèi)存碎片
訪問權(quán)限 只能局部變量 可以訪問全局變量
空間大小限制 操作系統(tǒng)限制 沒有特定的限制
內(nèi)存分配 連續(xù) 隨機(jī)分配
分配和釋放 編譯器指令自動管理 程序員手動管理
開銷
主要問題 空間小 內(nèi)存碎片
靈活性 固定大小 可以resize

這里可以根據(jù)實(shí)際需求來決定使用哪類內(nèi)存。

當(dāng)然,其實(shí)也不用關(guān)注那么多,我一般就是大內(nèi)存使用堆,局部變量小內(nèi)存使用棧。

這里還涉及到很多其它知識點(diǎn),比如進(jìn)程的內(nèi)存空間布局是怎么樣的,??臻g會不會污染、堆內(nèi)存具體是怎么分配和回收的。

具體在我的公眾號里搜索吧,里面有很多相關(guān)文章。

原文標(biāo)題:堆內(nèi)存和棧內(nèi)存的區(qū)別

文章出處:【微信公眾號:一口Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

審核編輯:彭靜

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

    關(guān)注

    8

    文章

    3055

    瀏覽量

    74329
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7614

    瀏覽量

    137714
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4346

    瀏覽量

    62971

原文標(biāo)題:堆內(nèi)存和棧內(nèi)存的區(qū)別

文章出處:【微信號:yikoulinux,微信公眾號:一口Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    談JVM xmx, xms等內(nèi)存相關(guān)參數(shù)合理性設(shè)置

    的,提高內(nèi)存占用(Memory Footprint)就有可能同時優(yōu)化這兩個標(biāo)的,這篇文章就來聊聊內(nèi)存相關(guān)內(nèi)容。 內(nèi)存占用一般指應(yīng)用運(yùn)行需要的所有內(nèi)存,包括
    的頭像 發(fā)表于 10-10 14:42 ?669次閱讀

    邏輯內(nèi)存和物理內(nèi)存的區(qū)別

    邏輯內(nèi)存和物理內(nèi)存是計(jì)算機(jī)系統(tǒng)中兩個重要的概念,它們在計(jì)算機(jī)的運(yùn)行和數(shù)據(jù)處理中起著至關(guān)重要的作用。 1. 物理內(nèi)存(Physical Memory) 物理
    的頭像 發(fā)表于 09-27 15:38 ?934次閱讀

    內(nèi)存緩沖區(qū)和內(nèi)存的關(guān)系

    內(nèi)存緩沖區(qū)和內(nèi)存之間的關(guān)系是計(jì)算機(jī)體系結(jié)構(gòu)中一個至關(guān)重要的方面,它們共同協(xié)作以提高數(shù)據(jù)處理的效率和系統(tǒng)的整體性能。
    的頭像 發(fā)表于 09-10 14:38 ?753次閱讀

    反射內(nèi)存卡的優(yōu)勢與特點(diǎn)

    特點(diǎn)1.高速數(shù)據(jù)傳輸:?反射內(nèi)存卡能夠?qū)崿F(xiàn)極高的數(shù)據(jù)傳輸速度,?這是其最顯著的特點(diǎn)之一。?數(shù)據(jù)傳輸速度可達(dá)到微秒級或百納秒級,?大大提升了數(shù)據(jù)處理的實(shí)時性。?這種高速傳輸能力使得反射內(nèi)存
    的頭像 發(fā)表于 09-05 16:28 ?409次閱讀
    反射<b class='flag-5'>內(nèi)存</b>卡的優(yōu)勢與<b class='flag-5'>特點(diǎn)</b>

    轉(zhuǎn)載 golang內(nèi)存分配

    Go 的分配采用了類似 tcmalloc 的結(jié)構(gòu).特點(diǎn): 使用一小塊一小塊的連續(xù)內(nèi)存頁, 進(jìn)行分配某個范圍大小的內(nèi)存需求. 比如某個連續(xù) 8
    的頭像 發(fā)表于 09-05 14:12 ?307次閱讀
    轉(zhuǎn)載 golang<b class='flag-5'>內(nèi)存</b><b class='flag-5'>分配</b>

    內(nèi)存管理的硬件結(jié)構(gòu)

    常見的內(nèi)存分配函數(shù)有malloc,mmap等,但大家有沒有想過,這些函數(shù)在內(nèi)核中是怎么實(shí)現(xiàn)的?換句話說,Linux內(nèi)核的內(nèi)存管理是怎么實(shí)現(xiàn)的?
    的頭像 發(fā)表于 09-04 14:28 ?396次閱讀
    <b class='flag-5'>內(nèi)存</b>管理的硬件結(jié)構(gòu)

    內(nèi)存時鐘和內(nèi)存條有什么不同

    在探討內(nèi)存時鐘(Memory Clock)和內(nèi)存條(Memory Module)的不同時,我們首先需要明確這兩個概念的基本定義和它們在計(jì)算機(jī)系統(tǒng)中的角色。以下是對這兩個概念的詳細(xì)解析,以及它們
    的頭像 發(fā)表于 09-04 11:45 ?1822次閱讀

    如何自定義內(nèi)存控制器的設(shè)置

    在FreeRTOS中自定義內(nèi)存控制器的設(shè)置,主要涉及到內(nèi)存分配策略的選擇和配置。FreeRTOS提供了多種內(nèi)存分配策略,如heap_1、he
    的頭像 發(fā)表于 09-02 14:28 ?575次閱讀

    堆棧和內(nèi)存的基本知識

    本文主要聊聊關(guān)于堆棧的內(nèi)容。包括堆棧和內(nèi)存的基本知識。常見和堆棧相關(guān)的 bug,如溢出,內(nèi)存泄漏,內(nèi)存
    的頭像 發(fā)表于 08-29 14:10 ?573次閱讀
    堆棧和<b class='flag-5'>內(nèi)存</b>的基本知識

    如何使用SystemView的監(jiān)控功能

    應(yīng)用中監(jiān)視所有,分析它們的使用情況,并展示收集到的信息,使用戶能夠查看的負(fù)載情況,發(fā)現(xiàn)潛在的內(nèi)存泄漏,跟蹤內(nèi)存使用峰值等等。
    的頭像 發(fā)表于 08-09 18:07 ?899次閱讀
    如何使用SystemView的<b class='flag-5'>堆</b>監(jiān)控功能

    FreeRTOS如何在中斷中調(diào)用內(nèi)存分配函數(shù)?

    最近在玩FreeRTOS,遇到一個問題,就是不知如何在中斷中調(diào)用內(nèi)存分配函數(shù)。pvPortMalloc函數(shù)中會調(diào)用xTaskResumeAll,而這個函數(shù)不能再中斷調(diào)用,所以請問在中斷中進(jìn)行內(nèi)存
    發(fā)表于 05-08 08:25

    你知道嗎? 51單片機(jī)也有動態(tài)內(nèi)存分配

    、realloc、free。他們的頭文件在中,所以使用內(nèi)存管理必須包含該頭文件。二、使用方法51單片機(jī)需要使用內(nèi)存管理API必須要手動調(diào)用初始化內(nèi)存管理函數(shù):init_
    的頭像 發(fā)表于 04-26 08:10 ?1642次閱讀
    你知道嗎? 51單片機(jī)也有動態(tài)<b class='flag-5'>內(nèi)存</b><b class='flag-5'>分配</b>

    C語言內(nèi)存泄漏問題原理

    內(nèi)存泄漏問題只有在使用內(nèi)存的時候才會出現(xiàn),內(nèi)存不存在內(nèi)存泄漏問題,因?yàn)?/div>
    發(fā)表于 03-19 11:38 ?574次閱讀
    C語言<b class='flag-5'>內(nèi)存</b>泄漏問題原理

    Linux內(nèi)核內(nèi)存管理之內(nèi)核非連續(xù)物理內(nèi)存分配

    我們已經(jīng)知道,最好將虛擬地址映射到連續(xù)頁幀,從而更好地利用緩存并實(shí)現(xiàn)更低的平均內(nèi)存訪問時間。然而,如果對內(nèi)存區(qū)域的請求并不頻繁,那么考慮基于通過連續(xù)線性地址訪問非連續(xù)頁幀的分配方案是有意義的。該模式
    的頭像 發(fā)表于 02-23 09:44 ?1079次閱讀
    Linux內(nèi)核<b class='flag-5'>內(nèi)存</b>管理之內(nèi)核非連續(xù)物理<b class='flag-5'>內(nèi)存</b><b class='flag-5'>分配</b>

    Linux內(nèi)核內(nèi)存管理之ZONE內(nèi)存分配

    內(nèi)核中使用ZONE分配器滿足內(nèi)存分配請求。該分配器必須具有足夠的空閑頁幀,以便滿足各種內(nèi)存大小請求。
    的頭像 發(fā)表于 02-21 09:29 ?949次閱讀