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

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

3天内不再提示

堆内存和栈内存的区别是什么

汽车电子技术 来源:程序喵大人 作者:程序喵大人 2023-02-21 13:54 次阅读

大家好,我是程序喵。

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

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


先介绍下栈内存:

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

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

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

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

可以看这两个动画

图片

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

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


那堆内存呢?

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

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

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

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

微信截图_20230105161930.png

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

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


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

图片

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


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

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

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

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

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

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

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

最后是 提问环节 ,大家可以在评论区讨论一下哈。

  • 当定义一个vector a(100); a在哪块内存?那100a的空间又在哪里?
  • 当定义一个array a; a在哪块内存,那100个a的空间又在哪里?

参考链接

https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap

https://www.guru99.com/stack-vs-heap.html

https://www.geeksforgeeks.org/stack-vs-heap-memory-allocation/

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

    关注

    13

    文章

    4296

    浏览量

    85799
  • 线程
    +关注

    关注

    0

    文章

    504

    浏览量

    19675
  • 栈空间
    +关注

    关注

    0

    文章

    5

    浏览量

    5438
收藏 人收藏

    评论

    相关推荐

    堆栈内存内存之间的区别

    编写有效的代码需要了解堆栈和内存,这使其成为学习编程的重要组成部分。不仅如此,新程序员或职场老手都应该完全熟悉堆栈内存内存之间的
    发表于 08-07 12:23 721次阅读
    堆栈<b class='flag-5'>内存</b>和<b class='flag-5'>堆</b><b class='flag-5'>内存</b>之间的<b class='flag-5'>区别</b>

    【原创】内存的那些事

    地址向高地址分配。在C语言中,内存在分配和释放的时候,是程序通过调用C语言的库函数完成的。这和内存的分配有区别
    发表于 07-12 09:48

    C语言单片机、堆栈的区别是什么?

    C语言单片机、堆栈的区别是什么?
    发表于 10-13 08:09

    STM32中的区别是什么

    区别是什么?的空间是如何进行分配的?
    发表于 11-29 07:05

    区别是什么

    在回答完进程的虚拟地址空间布局之后(上一篇),面试官可能抓住深入展开。区别①管理方式:
    发表于 12-22 07:26

    明确区分,究竟有什么区别?

    这条短短的一句话就包含了,看到new,我们首先就应该想到,我们分配了一块内存,那么指针p呢?他分配的是一块
    的头像 发表于 04-09 09:45 4423次阅读
    明确区分<b class='flag-5'>堆</b>与<b class='flag-5'>栈</b>,<b class='flag-5'>堆</b>和<b class='flag-5'>栈</b>究竟有什么<b class='flag-5'>区别</b>?

    一文看懂区别和联系

    本文开始介绍了的要点以及对的对比进行了分析,其次阐述了的联系,最后介绍了
    的头像 发表于 04-11 09:50 4.2w次阅读
    一文看懂<b class='flag-5'>堆</b>和<b class='flag-5'>栈</b>的<b class='flag-5'>区别</b>和联系

    C语言内存的笔记资料说明

    本文档的主要内容详细介绍的是C语言内存的笔记资料说明说明了C语言中区别,哪些数据存
    发表于 02-14 08:00 3次下载
    C语言<b class='flag-5'>内存</b><b class='flag-5'>堆</b>与<b class='flag-5'>栈</b>的笔记资料说明

    C语言程序的动态内存内存区域的概念

    C语言程序的动态内存分为内存区域和内存区域两种。内存
    的头像 发表于 06-29 10:34 1828次阅读

    什么是内存内存是如何分配的?

    在一般的编译系统中,内存的分配方向和内存是相反的。当内存从高地址向低地址增长的时候,
    的头像 发表于 07-05 17:58 9971次阅读

    嵌入式C语言中区别

    在嵌入式C语言中,都是用来存储变量的内存区域,但它们在存储和使用变量方面有很大的区别
    的头像 发表于 04-14 11:45 1394次阅读

    什么是内存?存储方式是什么样的?

    只有在内存里面才会发生内存泄漏的问题,在内存中不会发生内存泄漏。因为
    的头像 发表于 06-22 10:29 1174次阅读
    什么是<b class='flag-5'>堆</b><b class='flag-5'>内存</b>?存储方式是什么样的?

    程序内存分区中的

    (Heap)与(Stack)是开发人员必须面对的两个概念,在理解这两个概念时,需要放到具体的场景下,因为不同场景下,代表不同的含义。一般情况下,有两层含义: (1)程序
    的头像 发表于 11-11 16:21 755次阅读
    程序<b class='flag-5'>内存</b>分区中的<b class='flag-5'>堆</b>与<b class='flag-5'>栈</b>

    区别和使用注意事项

    是在计算机科学中广泛使用的两种数据结构,它们具有不同的用途和特点。区别涉及到内存
    的头像 发表于 01-18 17:24 2180次阅读

    C语言内存泄漏问题原理

    内存泄漏问题只有在使用内存的时候才会出现,内存不存在内存泄漏问题,因为
    发表于 03-19 11:38 521次阅读
    C语言<b class='flag-5'>内存</b>泄漏问题原理