什么是堆栈以及堆栈的区别

本文首发于公众号【程序员华仔】

------------------

首先说明下,这里讨论的堆和栈,是指程序内存中的“堆区”和“栈区”,并非是数据结构中所说的堆和栈。

要了解程序内存中的堆栈,需要先了解C语言的内存模型。

C语言的内存模型分为5个区:代码区,全局区,常量区,堆区和栈区。

1. 代码区

存放二进制代码区域,在ELF中称为.text段。

2.全局区

存放全局和静态变量的区域。

其中初始化的全局和静态变量在全局的一个区域,在ELF中取名为.data段。 

未初始化的全局变量和静态变量在临近一个区域, 在ELF中为.bss段。

全局区的内存由系统分配,并在程序结束后,由系统释放。

3.常量区

存储常量的区域。不允许修改。

该区的内存在程序结束的时候,由系统释放。

4.堆区(Heap)

存放程序员创建的变量的区域,是一块不连续的区域,一般使用new,alloc,calloc,malloc关键字创建的变量,这些变量需要程序员调用delete,release,free关键字才能释放。若没有调用,则会造成内存泄露。

5.栈区(Stack)

存放函数的参数,局部变量的区域,由编译器自动分配和释放。通常在作用范围域外就会释放变量。形式上类似于数据结构中栈。因为在CPU的指令集中分配内存,所以操作快且效率高。但是空间就很有限,例如iOS的栈区大小就是2M。

堆和栈概念

是一大块不连续的区域,一般使用数据结构中的链表来组织管理,在分配过程中,容易产出内存碎片。

是一小块连续的区域,一般使用队列按先进后出(First In Last Out)(FILO)的方式进行排序,并且只能在一端(栈顶(top))对数据进行插入和删除操作。

堆与栈区别

堆与栈,是操作系统对进程的内存空间的两种不同的管理方式,主要有如下几种区别:

(1)分配方式不同:

栈:由操作系统自动分配和释放,无需我们手动操作。分配方式类似数据结构中的栈。

堆:申请和释放工作由程序员自行完成,若程序员不释放,就会产生内存泄露。分配方式类似数据结构中的链表。

(2)空间大小不同:

栈:栈的空间大小远远小于堆。比如iOS栈为2M,64位的Linux默认10MB。

堆:理论上,进程可申请的堆大小为虚拟内存的大小。

(3)存放内容不同:

栈:存储函数返回地址、参数、局部变量和寄存器等内容。

堆:具体存放内容由程序员自定义填充。

(4)缓存方式不同:

栈:存放在一级缓存,被调用时放入存储空间中,调用完成就立即释放。

堆:存放在二级缓存中,一般使用引用计数(iOS)进行管理。

(5)数据结构不同:

堆:一般使用数据结构中的树来管理。

栈:一般使用先进后出的队列来管理。

(6)分配效率不同:

栈由操作系统自动分配,在CPU的指令集中完成分配并且有硬件层的支持(专门寄存器负责存储,专门指令负责压栈出栈)。

堆是由系统内核API接口来完成申请与管理,实现机制较为复杂,并且频繁的内存申请容易产生内存碎片。这样栈的分配效率比堆高多了。

以上就是堆栈的六大差异点。

iOS App内存布局

下面再看下iOS App的内存布局,下图所示。

正如上图所说一样,

1.整个内存空间中,最上面是高位地址,最下面是低位地址;

2.代码段和数据段位于最低地址位,即最底端;

3.在其之上的是堆,用来存放变量;对于ObjC来说,就是new,alloc,calloc,malloc关键字修饰的变量,堆的地址扩展方式是从低往高扩展,即当不够用的时候就往上申请空间地址

4.在往上就是栈了,主要存放函数的参数、局部变量等数据,它的扩展方式是从高往低扩展。

 

以上就是iOS App的内存布局情况,了解和掌握iOS App的内存布局情况,特别是堆栈分配以及扩展趋势,能帮助我们很好地分析定位问题。 

  • 14
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员华仔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值