本文部分内容整理于网络,感谢原作者。

堆(heap)和栈(stack)是C/C++编程不可避免会碰到的两个基本概念。首先,这两个概念都可以在讲数据 
结构的书中找到,他们都是基本的数据结构,虽然栈更为简单一些。 
在具体的C/C++编程框架中,这两个概念并不是并行的。对底层机器代码的研究可以揭示,栈是机器系 
统提供的数据结构,而堆则是C/C++函数库提供的。 
具体地说,现代计算机(串行执行机制),都直接在代码底层支持栈的数据结构。这体现在,有专门的寄 
存器指向栈所在的地址,有专门的机器指令完成数据入栈出栈的操作。 
这种机制的特点是效率高,支持的数据有限,一般是整数,指针,浮点数等系统直接支持的数据类型, 
并不直接支持其他的数据结构。因为栈的这种特点,对栈的使用在程序中是非常频繁的。对子程序的调 
用就是直接利用栈完成的。机器的call指令里隐含了把返回地址推入栈,然后跳转至子程序地址的操 
作,而子程序中的ret指令则隐含从堆栈中弹出返回地址并跳转之的操作。C/C++中的自动变量是直接利 
用栈的例子,这也就是为什么当函数返回时,该函数的自动变量自动失效的原因。

和栈不同,堆的数据结构并不是由系统(无论是机器系统还是操作系统)支持的,而是由函数库提供的。 
基本的malloc/realloc/free函数维护了一套内部的堆数据结构。当程序使用这些函数去获得新的内存 
空间时,这套函数首先试图从内部堆中寻找可用的内存空间,如果没有可以使用的内存空间,则试图利 
用系统调用来动态增加程序数据段的内存大小,新分配得到的空间首先被组织进内部堆中去,然后再以 
适当的形式返回给调用者。当程序释放分配的内存空间时,这片内存空间被返回内部堆结构中,可能会 
被适当的处理(比如和其他空闲空间合并成更大的空闲空间),以更适合下一次内存分配申请。这套复杂 
的分配机制实际上相当于一个内存分配的缓冲池(Cache),使用这套机制有如下若干原因:

1. 系统调用可能不支持任意大小的内存分配。有些系统的系统调用只支持固定大小及其倍数的内存请 
求(按页分配);这样的话对于大量的小内存分类来说会造成浪费。

2. 系统调用申请内存可能是代价昂贵的。系统调用可能涉及用户态和核心态的转换。

3. 没有管理的内存分配在大量复杂内存的分配释放操作下很容易造成内存碎片。

堆和栈的对比

从以上知识可知,栈是系统提供的功能,特点是快速高效,缺点是有限制,数据不灵活;而栈是函数库 
提供的功能,特点是灵活方便,数据适应面广泛,但是效率有一定降低。栈是系统数据结构,对于进 
程/线程是唯一的;堆是函数库内部数据结构,不一定唯一。不同堆分配的内存无法互相操作。栈空间 
分静态分配和动态分配两种。静态分配是编译器完成的,比如自动变量(auto)的分配。动态分配由 
alloca函数完成。栈的动态分配无需释放(是自动的),也就没有释放函数。为可移植的程序起见,栈的 
动态分配操作是不被鼓励的!堆空间的分配总是动态的,虽然程序结束时所有的数据空间都会被释放回 
系统,但是精确的申请内存/释放内存匹配是良好程序的基本要素。

在iOS中堆和栈区别

1.内存管理范围

  • 只有oc对象需要进行内存管理
  • 非oc对象类型比如基本数据类型不需要进行内存管理

2.内存管理本质

因为:Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由你释放的,就是release

OC对象存放于堆里面(堆内存要程序员手动回收)
非OC对象一般放在栈里面(栈内存会被系统自动回收)

堆里面的内存是动态分配的,所以也就需要程序员手动的去添加内存、回收内存

3.内存分配以及管理方式

按分配方式分

  • 堆是动态分配和回收内存的,没有静态分配的堆
  • 栈有两种分配方式:静态分配和动态分配
    • 静态分配是系统编译器完成的,比如局部变量的分配
    • 动态分配是有alloc函数进行分配的,但是栈的动态分配和堆是不同的,它的动态分配也由系统编译器进行释放,不需要程序员手动管理

按管理方式分

  • 对于栈来讲,是由系统编译器自动管理,不需要程序员手动管理
  • 对于堆来讲,释放工作由程序员手动管理,不及时回收容易产生内存泄露

网友总结:

堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,吃完之后还得清洗、打扫等后续工作(不然用完了不清洗就不好再用),但是比较符合自己的口味,而且自由度大。

栈是吃了吐 ,堆是吃了拉。

参考资料:

http://www.jianshu.com/p/c8e1d91dda99

https://my.oschina.net/jilin/blog/402054

iOS 堆和栈 的理解的更多相关文章

  1. 【转载】iOS堆和栈的理解

    操作系统iOS 中应用程序使用的计算机内存不是统一分配空间,运行代码使用的空间在三个不同的内存区域,分成三个段:“text segment “,“stack segment ”,“heap segme ...

  2. iOS 堆和栈的区别和联系

    堆和栈的区别主要有以下五点: 1.管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制:对于堆来讲,释放工作由程序员控制,容易产生memory leak(内存泄露). 2.申请大小: 栈是向低地 ...

  3. java 堆和栈一般理解

    栈与堆都是Java用来在Ram中存放数据的地方.与C++不同.Java自己主动管理栈和堆.程序猿不能直接地设置栈或堆.  Java的堆是一个执行时数据区,类的(对象从中分配空间.这些对象通过new.n ...

  4. 堆&栈的理解(转)

    (摘自:http://www.cnblogs.com/likwo/archive/2010/12/20/1911026.html) C++中堆和栈的理解 内存分配方面: 堆: 操作系统有一个记录空闲内 ...

  5. [c#基础]堆和栈

    前言 堆与栈对于理解.NET中的内存管理.垃圾回收.错误和异常.调试与日志有很大的帮助.垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这并不代表 ...

  6. C# 堆和栈的区别-该文转自:http://www.itcodes.cn/746.html | 程序人生

    理解堆与栈对于理解.NET中的内存管理.垃圾回收.错误和异常.调试与日志有很大的帮助.垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这并不代表程 ...

  7. 3.C#基础篇-->堆和栈

    一.前言 堆与栈对于理解.NET中的内存管理.垃圾回收.错误和异常.调试与日志有很大的帮助.垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这并不 ...

  8. 【转载】C#堆和栈的区别

    原文出处 理解堆与栈对于理解.NET中的内存管理.垃圾回收.错误和异常.调试与日志有很大的帮助.垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这 ...

  9. 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型

    小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...

随机推荐

  1. FVANCOP/ChartNew.js

    FVANCOP/ChartNew.js FVANCOP/ChartNew.js

  2. 利用FreeMarker静态化网页

    1.介绍-FreeMarker是什么 模板引擎:一种基于模板的.用来生成输出文本的通用工具 基于Java的开发包和类库 2.介绍-FreeMarker能做什么 MVC框架中的View层组件 Html页 ...

  3. Unity 安卓Jar包的小错误

    好久没写博客了,也就意味着好久没有学习了,近几天在搞Unity接入有米的SDk遇到了一点小错误,今天早上解决了,和大家分享下! 1,我们的目的是在在U3D中调用Android产生的Jar包,首先在Ec ...

  4. linux/module.h: No such file or directory 内核模块编译过程

    1.缺少Linux kernel头文件 To install just the headers in Ubuntu: sudo apt-get install linux-headers-$(unam ...

  5. 用maven骨架生成项目速度慢的问题

    最近从IntelliJ Idea 14的Community版本切换到Ultimate. 问题出现 最近从IntelliJ Idea 14的Community版本切换到Ultimate,key是从网络上 ...

  6. Sublime Text 添加到右键菜单 带菜单图标

    1.打开 regedit 2.找到节点 HKEY_CLASSSES_ROOT -> * -> Shell 3.右键选择新建“ 项 ” 这个项的名字将作为右键菜单的菜单名称,我用的“ Sub ...

  7. Model注解的后台原理

    Asp.net MVC的验证特性是由模型绑定器.模型元数据.模型验证器和模型状态组成的协调系统的一部分. 1.验证和模型绑定 默认情况下,Asp.net MVC框架在模型绑定石执行验证逻辑,在操作方法 ...

  8. 使用API查询天气

    服务端代码 [HttpPost] public ActionResult GetWeather() { HttpWebRequest request = (HttpWebRequest)HttpWeb ...

  9. [ofbiz]entitymode中类型的对照关系

    在实体数据结构的时候,习惯于数据库的设计模式,int,varchar等各种类型,但是在entitymode中不是直接使用数据库的类型模式,而是自己定义了一套数据类型(type). 如何找到两者之间的对 ...

  10. iBatis核心框架浅析

    1.1 iBatis配置与运行 1.dal 层的dao接口实现类通常会继承SqlMapClientDaoSupport.spring容器在初始化一个dao bean实例时,通常会注入两块信息DataS ...