美文网首页将来跳槽用
iOS程序的内存分配(栈区、堆区、全局区)

iOS程序的内存分配(栈区、堆区、全局区)

作者: Lxin_ | 来源:发表于2019-04-14 22:25 被阅读17次

应用程序在运行过程中,应用程序的数据都保存在内存中,不同类型的数据,保存的内存区域不同。

区名 存放数据
栈区 函数参数、局部变量
堆区 程序员申请的变量
全局区 全局变量、静态变量(静态全局变量/静态局部变量)
常量区 常量字符串、int常量等常量
代码区 函数的二进制代码

栈区

  • 栈区(stack) 由编译器自动分配并释放,存放函数的参数值,局部变量等。
  • 栈是系统数据结构,对应线程/进程是唯一的。
  • 优点是快速高效,缺点是有限制,数据不灵活。[先进后出]
  • 栈空间分静态分配和动态分配两种。静态分配是编译器完成的,比如自动变量(auto)的分配;动态分配由alloc函数完成。栈的动态分配无需释放(是自动的),也就没有释放函数。
  • 栈区的地址从高到低分配。
  • 为可移植的程序起见,栈的动态分配操作是不被鼓励的!

堆区

  • 堆区(heap) 由程序员分配和释放,如果程序员不释放,程序结束时,可能会由操作系统回收 ,比如在iOS中alloc都是存放在堆中。
  • 堆是函数库内部数据结构,不一定唯一。
  • 优点是灵活方便,数据适应面广泛,但是效率有一定降低。[顺序随意]
  • 堆空间的分配总是动态的,不同堆分配的内存无法互相操作。
  • 堆区的地址是从低到高分配。
  • 虽然程序结束时所有的数据空间都会被释放回系统,但是精确的申请内存,释放内存匹配是良好程序的基本要素。

全局区(静态区)

  • 全局(静态)区包含下面两个分区:数据区(data)
  1. 初始化全局区--数据区(data区):存放已初始化全局变量和静态变量
  2. 未初始化全局区--BSS区:存放未初始化全局变量和静态变量

文字常量区

  • 存放的就是字符串常量,int常量等常量。
  • 程序结束后由系统释放。

代码区

  • 存放函数的二进制代码
  • 代码段需要防止在运行时被非法修改,所以只准许读取操作,而不允许写入(修改)操作。
#import "ViewController.h"

int a = 1; //全局变量分配在全局区
static int b = 2; //静态全局变量分配在全局区

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    static int c = 3; //静态局部变量分配在全局区

    int d = 4; //局部变量分配在栈区

    NSString *string = @"abcd"; //string局部变量分配在栈区,@"abcd"字符串分配在文字常量区
    NSArray *array = [[NSArray alloc] init]; //array局部变量分配在栈区,后面创建的OC对象分配在堆区,栈区的指针指向堆区的对象。
}

@end

内存分区示意图

内存分区示意图

栈区和堆区的比较

  • 分配方式不同
    栈区:是由编译器自动分配和释放;
    堆区:是由程序员来分配和释放。
  • 申请后系统的响应
    栈区:栈区内存由编译器分配和释放,在函数执行时分配,在函数结束时收回。只要栈区剩余内存大于所申请的内存,那么系统将为程序提供内存。
    堆区:系统有一个存放空闲内存地址的链表,当程序员申请堆内存的时候,系统会遍历这个链表,找到第一个内存大于所申请内存的堆节点,并把这个堆节点从链表中移除。由于这块内存的大小很多时候不是刚刚好所申请的一样大,所以剩余的那一部分还会回到这个空闲链表中。
  • 申请大小的限制
    栈区:栈区是向低地址扩展的数据结构,也就是说栈顶的地址和栈的容量大小是由系统决定的。栈的容量大小一般是2M(也有的说是1M,总之是一个编译时就确定的常数 ),当申请的栈内存大于2M时就会出现栈溢出。因此栈可分配的空间比较小。
    堆区:堆是向高地址扩展的数据结构,是不连续的。堆的大小受限于计算机系统中有效的虚拟空间,因此堆可分配的空间比较大。
  • 申请效率的比较
    栈:栈由系统自动分配,速度较快,但是不受程序员控制。
    堆:堆是由alloc分配的内存,速度较慢,并且容易产生内存碎片。

相关文章

  • iOS知识梳理12:堆和栈

    相关连接iOS程序中的内存分配 栈区堆区全局区 内存分区 1.栈区(stack) 由编译器自动分配并释放,存放函数...

  • 栈/堆/全局区/常量区/代码区

    来源:iOS程序中的内存分配 栈区堆区全局区 - 简书 栈:存储局部变量 堆:允许程序员手动在堆区申请指定的连续的...

  • 内存5大区

    iOS程序中的内存分配分为5大区 内存5大区:堆,栈,方法区,全局区,常量区 栈:不需要手动管理内存,会自动清理栈...

  • iOS 内存五大区

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

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

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

  • iOS内存分配五大区:

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

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

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

  • C++第五弹---堆与拷贝构造函数

    动态内存分配 关于堆C++程序的内存格局通常分为四个区:全局数据区、代码区、栈区、堆区 全局变量、静态数据、常量存...

  • iOS -内存分配(非原创)

    内存分为:栈区,堆区,静态区(全局区),常量区,代码区 一、预备知识—程序的内存分配一个由C/C++编译的程序占用...

  • iOS内存分配

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

网友评论

    本文标题:iOS程序的内存分配(栈区、堆区、全局区)

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