iOS 内存管理(一):内存五大区

2,695 阅读3分钟

总览

在iOS中,内存主要分为五大区域:栈区堆区全局/静态区常量区代码区,布局结构如下图所示:

image.png

一、栈区

  • 栈是一块连续的内存区域从高地址向低地址进行存储,遵循先进后出(FILO)原则。
  • 栈的地址空间在 iOS 中是以0X7开头。
  • 栈区一般在运行时分配,内存空间由系统管理,申明的变量过了作用域范围后内存便会自动释放。
  • 函数内部定义的局部变量方法的参数(方法中默认参数:selfcmd),都存放在栈区。

优缺点

  • 优点:栈是由系统自动分配并释放的,不会产生内存碎片,所以快速高效。
  • 缺点:栈的内存大小有限制,数据不灵活,iOS 主线程栈大小是1MB其他线程512KB,MAC 只有 8M,信息来自 官方文档6203393-3e4f3c061f3ab80d.png

验证

- (void)testStack {
    int a = 10;

    NSLog(@"a == %p size == %lu",&a,sizeof(a));
    NSLog(@"方法参数 self:%p",&self);
    NSLog(@"方法参数 cmd:%p",&_cmd);
}

打印结果:
a == 0x7ffeee47d75c size == 4
方法参数 self0x7ffeee47d768
方法参数 cmd:0x7ffeee47d760

二、堆区

  • 堆是不连续的内存区域从低地址向高地址进行存储,,类似于链表结构(便于增删,不便于查询),遵循先进先出(FIFO)原则。
  • 堆的地址空间在iOS中是以0x6开头,其空间的分配总是动态的。
  • 开发人员需要关注变量的生命周期,如果不及时释放,会造成内存泄漏,只有等程序结束时由系统统一回收。
  • OC中使用alloc或者new开辟空间创建对象。
  • C语言中使用malloccallocrealloc分配的空间,需要free释放。

优缺点

  • 优点:获得空间灵活,分配内存较大。
  • 缺点:需手动管理,速度慢、容易产生内存碎片。

验证

- (void)testHeap {
    NSObject *object1 = [NSObject new];
    NSObject *object2 = [NSObject new];
    NSLog(@"object1 = %@",object1);
    NSLog(@"object2 = %@",object2);
}

打印结果:
object1 = <NSObject: 0x600002b8f430>
object2 = <NSObject: 0x600002b8f420>

三、全局/静态区

  • 该区是编译时分配的内存空间,在iOS中一般以0x1开头,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放。
  • 未初始化的全局变量和静态变量,即BSS区(.bss)。
  • 已初始化的全局变量和静态变量,即数据区(.data)。

验证

int clB = 10;
static int bssB = 10;

- (void)test {
    NSLog(@"clA == %p",&clA);
    NSLog(@"clB == %p",&clB);
}

打印结果:
clA == 0x104131424
clB == 0x104131408

四、常量区(即.rodata)

  • 该区是编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放。
  • 存放常量:整型字符型浮点字符串等。

验证

借助MachOView查看常量区:

image.png

五、代码区

  • 该区是编译时分配的内存空间,在程序运行过程中,此内存中的数据一直存在,程序结束后由系统释放。
  • 程序运行时的代码会被编译成二进制,存进内存的代码区域。

验证

借助MachOView查看代码区:

image.png