美文网首页你好 苹果iOS
iOS内存分配:堆、栈、全局区、常量区、代码区

iOS内存分配:堆、栈、全局区、常量区、代码区

作者: 四月_Hsu | 来源:发表于2019-10-31 17:24 被阅读0次

前言

内容参考:

iOS 内存分配 栈、堆、全局区、常量区、代码区

NSString存储管理--NSTaggedPointerString

iOS开发中的内存分配(堆和栈)

分析

iOS内存分配.png

1. 代码区

代码区是用来存放函数的二进制代码,也就是,它是可执行程序在内存中的镜像。代码段需要防止在运行时被非法修改,所以只允许读取操作,而不允许写入操作。

2. 全局(静态)区

  • 数据区:数据段用来存放可执行文件中已经初始化的全局变量,也就是用来存放静态分配的变量和全局变量。
  • BSS区:BSS段包含了程序中未初始化的全局变量

3. 常量区

常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量。

4. 堆(heap)区

堆是由程序员分配和释放,用于存放进程运行中被动态分配的内存段。它大小不固定,可动态扩张和缩减。

5. 栈(stack)区

栈是由编译器自动分配释放来管理内存。用户存放程序临时创建的变量、存放函数的参数值、局部变量等。由于栈的先进后出特点,所以特别适合用来做保存/恢复现场的操作。从这个吧意义上,我们可以把栈看做一个临时寄存、交换的内存区。

static 修饰的属性始终保存到常量区。

上述几种内存区域中,数据段、BSS、堆通常都是被连续存储的-内存位置上的连续(并不是堆链式存储的内存区域)。而代码段和栈往往会被独立存放。

栈是向低地址扩展的数据结构,是一块连续的内存区域。堆是向高地址扩展的数据结构,是不连续的内存区域。

内存模型 Heap、Stack

以下内容引用自阮一峰老师的 汇编语言入门教程

对于堆 heap 和 栈 stack 描述更加详细易懂。

1. 堆 Heap

寄存器只能存放少量的数据,大多数时候, CPU 还要指挥寄存器,直接跟内存交换数据,所以,除了寄存器,还必须了解内存怎么存储数据。

程序运行的时候,操作系统会给它分配一块内存,用来存储程序和运行产生的数据,比如从 0x10000x8000,起始地址是较小的那个地址,结束地址是较大的那个地址。

内存示意图

程序运行过程中,对于动态的内存占用请求(比如新建对象),系统就会从预先分配好的那段内存中,划出一部分给用户,具体规则是从起始地址开始划分(实际上,起始地址会有一段静态数据,这里忽略)。举例来说,用户要求得到10个字节内存,那么从起始地址 0x1000 开始给他分配,一直分配到 0x100A,如果在要求得到 22 个字节,那么就分配到 0x1020

内存分配

这种因为用户主动请求而划分出来的内存区域,叫做 Heap(堆)。它由起始位置开始,从低位(地址)向高位(地址)增长。 Heap 的一个重要特点就是不会自动消失,必须手动释放,或者由垃圾回收机制来回收。

2. 栈 Stack

除了 Heap 外,其他的内存占用叫做 Stack(栈)。简单来说,Stack 是由于函数运行而临时占用的内存区域。

栈内存

请看下面的例子:

int main() {
    int a = 2;
    int b = 3;
}

上面代码中,系统开始执行 main 函数时,会为它在内存里面建立一个 帧(frame),所有的 main 的内部变量(比如 ab)都保存在这个 里面。main 函数执行结束后,该帧就会被回收,释放所有的内部变量,不再占用空间。

帧(frame)

如果函数内部调用其他函数,会发生什么情况呢?

int main() {
    int a = 2;
    int b = 3;
    return add_a_and_b(a,b);
}

上面代码中,main 函数调用了 add_a_and_b 函数。执行到这一行的时候,系统也会为 add_a_and_b 新建一个 帧(frame),用来存储它的内部变量。也就是说,此时同时存在两个帧:mainadd_a_and_b。一般来说,调用栈有多少层,就有多少帧。

函数嵌套

等到 add_a_and_b 运行结束,它的帧就会被回收,系统会回到刚才 main 函数中断执行的地方,继续往下执行。通过这种机制,就实现了函数的层层调用,并且每一层都能使用自己的本地变量。

所有的帧都存放在 Stack ,由于帧是一层层叠加的,所以 Stack 叫做 。生成新的帧,叫 入栈,英文单词是 push;栈的回收叫 出栈,英文是 popStack 的特点就是,最晚入栈的帧最早出栈(因为最内层的函数调用,最先结束执行),这种叫做 后进先出 的数据结构。每一次函数执行结束,就自动释放一个帧,所有的函数执行结束,整个 Stack 就都释放了。

Stack 是由内存区域的结束地址开始,从高位(地址)向地位(地址)分配。比如,内存区域的结束地址是 0x8000,第一帧假定是 16 字节,那么下一次分配的地址就会从 0x7FF0 开始;第二帧假定需要 64 字节,那么地址就会移到 0x7FB0

栈内存地址分配

关于 NSString 的内存分配

NSString存储管理--NSTaggedPointerString 文章中详细说明了问题,我们并不能单纯的通过打印内存地址,来判断数据存储的区域在常量,或者堆区、栈区。

相关文章

  • iOS内存分配:堆、栈、全局区、常量区、代码区

    前言 内容参考: iOS 内存分配 栈、堆、全局区、常量区、代码区 NSString存储管理--NSTaggedP...

  • iOS内存分配五大区:

    iOS内存分配五大区: 栈区,堆区,静态区(全局区),常量区,代码区 动态数据区一般就是”堆栈”,栈是线性结构,堆...

  • 19·iOS 面试题·什么是 ARC ?(ARC 是为了解决什么

    前言 对于 iOS 内存分区有:栈区、堆区、静态区、全局区、常量区、代码区。对于静态区、全局区、常量区、代码区,对...

  • iOS内存分配

    iOS的内存分配大致可以分为以下五种:代码区、全局/静态区、常量区、堆区和栈区。 占用内存的行为 创建对象 定义变...

  • iOS内存相关问题小结

    1.iOS内存 IOS 内存区主要可以划分为五个区,栈区、堆区、全局变量区、常量区、代码区。 栈区:系统负责内存管...

  • OC底层探索21-内存五大区域

    iOS设备中,内存被人为的分成5大区域:栈区、堆区、全局/静态区、常量区、代码区,所占内存都为系统分配的虚拟内存。...

  • 谈谈内存分配

    内存分区: iOS中主要是栈区(stack)、堆区(heap)、全局区/静态区(staic) 、常量区、代码区; ...

  • iOS 内存五大区

    在 iOS 开发中,内存主要分为堆区、栈区、全局区、常量区、代码区五大区域 堆(heap)区 是有程序员分配和释放...

  • iOS 内存简单介绍

    iOS内存管理 iOS内存分为5个区:栈区,堆区,全局区,常量区,代码区 栈区stack:这一块区域系统会自己管理...

  • iOS 内存基础知识及堆区和栈区的区别

    iOS内存区域大致分为;栈区,堆区,全局区(静态区),文字常量区,程序代码区 栈区 栈区(stack)由编译器自动...

网友评论

    本文标题:iOS内存分配:堆、栈、全局区、常量区、代码区

    本文链接:https://www.haomeiwen.com/subject/ltitbctx.html