0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

什么是堆内存与栈内存?它们的分配和回收有什么特点?

xCb1_yikoulinux 来源:程序喵大人 作者:程序喵大人 2022-07-01 10:33 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

这篇文章分享一个面试中经常被问到的知识点:堆内存和栈内存有什么区别?平时开发应该使用堆内存还是栈内存?

要回答这个问题,我们首先需要知道什么是堆内存,什么是栈内存,它们的分配和回收有什么特点?

先介绍下栈内存:

栈内存是为线程留出的临时空间,每个线程都有一个固定大小的栈空间,而且栈空间存储的数据只能由当前线程访问,所以它是线程安全的。

栈空间的分配和回收是由系统来做的,我们不需要手动控制。

当一个函数调用时,系统就会为该函数的调用分配栈空间,当函数返回后,系统就会自动回收这块空间,同理,下次其它函数调用和返回,系统还是会自动分配和回收空间。

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

可以看这两个动画

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

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

栈空间的大小是固定的,它有一个水位线,标识栈空间的分配状态,水位线里面的表示已经分配,然后这个水位线会根据函数调用和返回的情况自动调整。

这里可以看到,栈空间的分配和回收非常简单,只需要调整水位线位置就可以了,没有任何多余操作。

那堆内存呢?

我们平时在C语言C++中使用malloc和new分配的内存就是堆内存,堆内存的一大特点就是大小不固定,可以动态扩容,空间由程序员动态分配,更加灵活。

然而,既然有优点也必然伴随着缺点。

第一个缺点就是它容易产生内存泄露,malloc出来的没有free,new出来的如果没有delete,都会产生内存泄露,真正项目内存泄露产生的情况肯定比这个复杂的多。

第二个缺点,容易产生内存碎片,在分配和回收时需要对很多内存碎片进行整理,效率较低,具体可以看这个动画。

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

所以才会有很多自定义的内存分配器,但它肯定还是没有栈空间分配回收速度快。

第三个缺点,线程不安全,它不像栈内存是线程独立的,堆内存可以被一个进程内所有的线程访问,多线程操作就容易产生问题,很多奇奇怪怪的操作就是这么引起的。

那什么变量存储在栈上,什么存储在堆上呢?普通的A a,这种就是都存储在栈上,当使用new和malloc分配的空间会存储在堆上,看这个图:

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

new出来的实际空间是在堆上分配,然后在栈上开辟一个指针大小的空间,这个空间有一个指针,指向堆上的那块内存,这样给变量和堆内存之间就关联起来了。

那什么情况下使用栈内存,什么情况下使用堆内存呢?

我整理出来了一个表,贴在这里:

速度
空间管理 高效,不会产生碎片 会产生内存碎片
访问权限 只能局部变量 可以访问全局变量
空间大小限制 操作系统限制 没有特定的限制
内存分配 连续 随机分配
分配和释放 编译器指令自动管理 程序员手动管理
开销
主要问题 空间小 内存碎片
灵活性 固定大小 可以resize

这里可以根据实际需求来决定使用哪类内存。

当然,其实也不用关注那么多,我一般就是大内存使用堆,局部变量小内存使用栈。

这里还涉及到很多其它知识点,比如进程的内存空间布局是怎么样的,栈空间会不会污染、堆内存具体是怎么分配和回收的。

具体在我的公众号里搜索吧,里面有很多相关文章。

原文标题:堆内存和栈内存的区别

文章出处:【微信公众号:一口Linux】欢迎添加关注!文章转载请注明出处。

审核编辑:彭静

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    9

    文章

    3173

    浏览量

    76113
  • C语言
    +关注

    关注

    183

    文章

    7642

    浏览量

    144600
  • 函数
    +关注

    关注

    3

    文章

    4406

    浏览量

    66833

原文标题:堆内存和栈内存的区别

文章出处:【微信号:yikoulinux,微信公众号:一口Linux】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    从代码执行看单片机内存分配

    需要分配给它们的空间大小(并且等于代码所生成的.bin文件大小),另外RW-data和ZI-data存储在sram中,同样两者之和为单片机中sram需要分配给它们的空间大小。 另外,我们必然会想到
    发表于 12-02 07:58

    的区别

    一个由C/C 编译的程序占用的内存分为以下几个部分: 区(stack):由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的
    的头像 发表于 11-27 18:13 902次阅读

    如何在应用程序调试期间分析使用情况

    随着 AMD Vitis 统一软件平台 2021.2 的发布,Vitis 引入了一个 Tcl 脚本,用于在应用程序运行的特定时间点协助查找内存使用情况。该脚本已延续到后续的 Vitis 版本
    的头像 发表于 10-24 16:54 584次阅读
    如何在应用程序调试期间分析<b class='flag-5'>栈</b>和<b class='flag-5'>堆</b>使用情况

    WebGL/Canvas 内存泄露分析

    的 JavaScript 对象未释放要复杂得多。一个现代 WebGL/Canvas 应用的内存版图实际上跨越了三个截然不同但又相互关联的内存区域: 图 V8 引擎管理的 JavaScript (JS Heap
    的头像 发表于 10-21 11:40 167次阅读
    WebGL/Canvas <b class='flag-5'>内存</b>泄露分析

    FAQ_MA35_Family M4 RAM如何调整M4的内存分配

    FAQ_MA35_Family M4 RAM如何调整M4的内存分配
    发表于 09-02 06:07

    stm32cubeIDE使用malloc失败是什么原因?

    我在stm32cubeIDE环境下,已经分配了足够的空间,但是我在的使用malloc分配内存时,一直
    发表于 06-09 07:24

    stm32cubeIDE使用malloc失败是什么原因?

    我在stm32cubeIDE环境下,已经分配了足够的空间,但是我在的使用malloc分配内存时,一直
    发表于 06-04 07:18

    华强北TF卡回收 内存回收

    深圳帝欧电子求购内存SD卡2G,4G,8G,16G,32G,64G,128G,256G,512G......新卡,旧卡,拆机卡都有收,价高同行回收三星内存TF卡、金士顿TF卡、闪迪TF卡、东芝TF卡
    发表于 05-21 17:48

    stm32cubeIDE使用malloc失败的原因?

    我在stm32cubeIDE环境下,已经分配了足够的空间,但是我在的使用malloc分配内存时,一直
    发表于 04-27 06:45

    如何使用LAX_CODEGEN启用动态内存分配

    我目前正在探索NXP_MBDToolbox_LAX。lax_codegen 生成的代码基于静态分配。我想管理大型向量,如何使用 LAX_CODEGEN 启用动态内存分配
    发表于 04-10 08:09

    如何查看S32DS中S32平台的内存分配

    大家好,我正在使用 s32DS for s32 平台,我想查看我的项目的内存分配。我想知道分配给对象的内存以及它们
    发表于 04-09 07:30

    golang内存分配

    作者:钱文 Go 的分配采用了类似 tcmalloc 的结构.特点: 使用一小块一小块的连续内存页, 进行分配某个范围大小的内存需求. 比如
    的头像 发表于 03-31 15:00 383次阅读
    golang<b class='flag-5'>内存</b><b class='flag-5'>分配</b>

    快速搞懂C语言程序内存分区!

    到动态分配的数据等内容。(内存分区图示)理解这些内存分区的结构和特性,不仅有助于编写更高效的代码,还能帮助排查和解决如段错误、内存泄漏、
    的头像 发表于 03-14 17:37 1331次阅读
    快速搞懂C语言程序<b class='flag-5'>内存</b>分区!

    hyper v 内存,hyper v 内存设置的操作步骤和方法是什么?

    在利用Hyper-V搭建和管理虚拟机的过程中,合理设置虚拟机的内存至关重要。内存分配是否恰当,会直接影响到虚拟机的运行性能和稳定性。若内存分配
    的头像 发表于 01-24 15:22 1092次阅读
    hyper v <b class='flag-5'>内存</b>,hyper v <b class='flag-5'>内存</b>设置的操作步骤和方法是什么?

    养成良好的编程习惯|内存初值不一定是0

    ;} 代码很简单,使用 malloc 申请一段内存,假设内存空间足够大。 通过 getchar 配合 while 循环,从标准输入获取一个字符串,直到遇到换行符结束。 最后就是把获取的字符串输出。 乍一看,好像程序没什么问题。
    的头像 发表于 12-18 09:14 573次阅读