iOS堆和栈的区别(一)

623 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

堆和栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。

堆:队列优先,先进先出(FIFO—first in first out)。

栈:先进后出(FILO—First-In/Last-Out)。

堆栈空间分配

1.栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量等值。其操作方式类似于数据结构中的栈。

2.堆区(heap):一般由程序员分配释放,若程序员不释放,则可能会引起内存泄漏。其类似于链表。

堆栈缓存方式

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

image.png

代码区(text segment ):是应用程序运行时应用程序代码存在的内存段,运行前就已经确定(编译时确定),通常为只读的。代码区的指令中包括操作码和要操作的对象(或对象地址引用),代码区指令根据程序设计流程依次执行,每一个指令,每一个单个函数、过程、方法和执行代码都存在这个内存段中直到应用程序退出。一般使用中很少涉及。

栈(Stack):当我们创建一个值类型,如结构体,系统将其存储在一个被称为栈的内存区域中,是由CPU直接管理和优化的。当一个函数声明一个变量,变量将存储在栈中,当函数调用完毕后栈会自动释放该变量。因此栈是非常易于管理的、有效的,由于是CPU直接控制,速度非常快。

堆(Heap):当我们创建了一个引用类型,如类,系统将把类实例存储在一个被称为堆的内存区域中。系统使用堆来存储其他对象引用的数据。堆是一个大的内存池,系统可以从该池中请求并动态分配内存块。堆不会像栈一样自动释放对象,需要额外的工作来完成。这使得在堆中创建和删除数据比栈慢。

栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放。堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。

stack 中的一个指针仅仅是一个整型变量,保存了heap(堆)中特定内存地址的数据。简而言之,操作系统使用stack 段中的指针值访问heap 段中的对象。如果stack 对象的指针没有了,则heap 中的对象就不能访问。这也是内存泄露的原因。

在iOS 操作系统的stack 段和heap 段中,你都可以创建数据对象。stack 对象的优点主要有两点,一是创建速度快,二是管理简单,它有严格的生命周期。stack 对象的缺点是它不灵活。创建时长度是多大就一直是多 大,创建时是哪个函数创建的,它的owner 就一直是它。不像heap 对象那样有多个owner ,其实多个owner 等同于引用计数。只有 heap 对象才是采用“引用计数”方法管理它。

堆栈数据结构区别

堆(数据结构):堆可以被看成是一棵树,如:堆排序。

栈(数据结构):一种先进后出的数据结构。