对于栈内存和堆内存的理解

1.和堆一样存储在计算机RAM中
2.栈是为执行线程留出的内存空间
3.栈附属于线程,因此当线程结束时栈被回收
4.线程被创建的时候,设置栈的大小
5.当用栈过多时会导致栈溢出(无穷次/大量的递归调用,或者大量的内存分配)
6.如果在编译之前精确的知道要分配数据的大小并且不是太大的时候,可以使用栈

栈底层

1.栈经常与sp寄存器一起工作,最初sp指向栈顶
2.CPU用push指令将数据压栈,用pop指令来弹栈。压栈时sp值减少,弹栈时sp值增大,存取和获取数据都是CPU寄存器的值
3.当函数被调用时,CPU使用特定的指令把当前的IP(存放偏移地址的一个寄存器)压栈,即执行代码的地址,CPU接下来将调用函数地址赋给IP,进行调用,当函数返回时,旧的IP被弹栈,CPU继续执行函数调用之前的代码。
4.当进入函数时,sp向下扩展,扩展到确保为函数的局部变量留存足够大小的空间。当函数返回时,sp通过返回原来的位置来释放空间。
5.如果函数有参数的话,在函数调用之前,会将参数压栈,函数中的代码通过sp的当前位置来定位参数并访问他们。
6.栈要受到内存块的限制,不断的函数嵌套/为局部变量分配太多的空间,可能会导致栈溢出。当栈中的内存区域都已经被使用完之后继续向下写(低地址),会触发一个CPU异常。

1.和栈一样存储在计算机RAM中
2.堆是为动态分配预留的内存空间
3.堆通常通过运行时在应用程序启动时被分配,当应用程序(进程)退出时被回收
4.在应用程序启动的时候,设置堆的大小,但是可以在需要的时候进行扩展
5.如果申请的缓冲区过大的话,可能申请失败
6.在运行期间不知道会需要多大的数据或者需要分配大量的内存的时候,建议使用堆

堆底层

1.堆包含一个链表来维护已用和空闲的内存块。在堆上新分配内存是从空闲的内存块中找到一些满足要求的合适块,这个操作会更新堆中的块链表。
2.堆增加新块通常从低地址向高地址扩展。因此可以认为堆随着内存分配而不断的增加大小。
3.申请和释放许多小的块可能会产生如下状态:在已用块之间存在很多小的空闲块,进而申请大块内存失败,虽然空闲块的总和足够,但是空闲的小块是零散的,不能满足申请的大小,也就是堆碎片。
4.当旁边有空闲块的已用块被释放时,新的空闲块可能会与相邻的空闲块合并为一个大的空闲块,这样可以有效的减少堆碎片的产生。

每一个线程都有一个栈,但是每一个应用程序通常都只有一个堆(为不同类型分配内存使用多个堆的情况也是有的)。 栈比堆要快,因为它的存取模式使它可以轻松的分配和重新分配内存(指针/整型只是进行简单的递增或者递减运算),所有的空闲内存都是连续的。

点击查看参考的栈和堆底层的相关原文

点击查看栈和堆存储数据的区别,可以借鉴一下这篇文章

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值