探寻iOS内存分配

作者: sweetpf | 来源:发表于2017-09-08 09:10 被阅读886次
所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等。不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内存是事先静态分配和统一回收的,而有些却是按需要动态分配和回收的。

下图是iOS系统为一个APP分配的内存,如下:


内存.png

内存分类(RAM、ROM)

  • RAM:运行内存,不能掉电储存;
  • ROM:储存性内存,可以掉电储存,例如:内存卡,flash;
  • RAM的访问速度要远高于ROM,价格也要高;
  • CPU只能从RAM直接读取指令;
  • app程序一般存放于ROM中。启动app时,系统会把开启的app程序从ROM中转移到RAM中。

内存分区

iOS中主要是栈区(stack)、堆区(heap)、全局区/静态区(staic) ;

栈区

  • 存放局部变量,先进后出,一旦出了作用域就会被销毁,函数跳转地址,现场保护等
  • 栈区的地址从高到低分配

堆区

  • 堆区的内存分配使用的是alloc;
  • 堆区的地址是从低到高分配;
  • ARC原理是基于堆区,编译器在编译的时候给对象自动添加retain,release,autorelease;
  • 在ios中,堆区的内存是应用程序共享的,堆中的内存分配是系统负责的;

全局区

  • 包括2个部分:未初始化和初始化; 也是说,在内存中是放在一起的,比如:int a;未初始化, int a = 10 初始化的 2者都在全局区/静态区;
    常量区:常量字符串及时放在这里的;
    代码区:存放app代码;

tips:

  • 堆区需要程序猿管理内存,是由alloc分配的内存,一般速度比较慢,容易产生内存碎片;
  • 栈区不需要程序猿管理内存,由编译器自动分配并释放,速度快;
  • 当一个app启动后,代码区,常量区,全局区大小都是已经固定的,因此指向这些区的指针不会产生崩溃性的错误,而堆区和栈区是时时刻刻变化的(堆得创建和销毁,栈的弹入和弹出),所以当使用一个指针指向这个2区里面内存的时候,一定要注意内存是否已经被释放,否则会产生程序崩溃(即野指针报错)

iOS的内存管理

这里按照苹果文档所述,重点对堆内存分配整理下。
首先,iOS和其它系统一样,内存分页,每页4K。多个页构成一个region统一管理,负责管理的对象是VM object,其中包含了pager、size、resident pages等诸多属性。不管是Objective-C的[NSObject alloc],还是C代码的对内存分配,最终重任都会落到malloc库上,释放也是如此,最终都将使用malloc库中的free()。
malloc库中有很多malloc的同族函数可以动态分配内存,会结合参数在free pages中进行最适分配。如果分配的内存比较大,可以直接使用vm_allocate,得到一个VM对象(与Linux类似),这个在实际使用前不分配物理内存。malloc的内部实现都是开源的,感兴趣的可以去了解去看。
此外,对于malloc,还有一个Zone的概念(貌似与Linux的概念不完全相同),可以简单理解为一组free page单元,可以统一管理操作。默认情况,在第一次调用malloc时,系统会生成一个default zone,后续的默认分配在此进行。比如,malloc_zone_xxx()函数都是对特定的zone进行分配操作,执行zone->xxx()。

最后强调一下iOS特别需要注意的点:
当前的主流iPhone实际物理内存都不超过1G,可以说不算大。不过和Android机比起来,我不得不为苹果的设计称赞,1G空间利用得如此高效,性能不差,也控制了发热。

验证示例:

未完待续

iOS引用计数原理

- 引用计数机制只使用在堆中,那么所有不保存在堆中的数据的引用计数都为-1。
- 在OC中几乎所有不可变对象(常量)都存在常量区,内存管理由系统来做,引用计数为-1。
- 对象引用计数降至0,那么对象所在的内存也许会回收。
- retain 递增引用计数
- release 递减引用计数
- autorelease 清理「自动释放池」时,在递减保留计数
> [参考](http://www.jianshu.com/p/67970ff59ffc)

致谢:

感谢“三石的博客”的作品

相关文章

  • 探寻iOS内存分配

    下图是iOS系统为一个APP分配的内存,如下: 内存分类(RAM、ROM) RAM:运行内存,不能掉电储存; RO...

  • 探索iOS内存分配

    探索iOS内存分配 探索iOS内存分配

  • iOS 性能优化 - Allocations分析内存分配

    iOS 性能优化 - Allocations分析内存分配 iOS 性能优化 - Allocations分析内存分配

  • iOS底层探究 - 内存对齐

    目录1:内存对齐的原因2:内存对齐的规则3:结构体内存分配演练以及在iOS中对象成员的内存分配探索 一 :内存对齐...

  • iOS内存分配

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

  • iOS内存分配

    1 RAM&ROM RAM与ROM就是具体的存储空间,统称为存储器。 RAM(random access memo...

  • iOS内存分配

    摘自阳君的博客 1. RAM&ROM RAM与ROM就是具体的存储空间,统称为存储器。 1.RAM(random ...

  • iOS内存分配

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

  • iOS内存分配

    iOS对象有3种: 实例对象 类对象 元类对象 对象(对象都是结构体)的内存中,包含的指针: isa 实例对象is...

  • iOS 内存分配

    1.栈区(stack) 由编译器自动分配并释放,存放函数的参数值,局部变量等。栈是系统数据结构,对应线程/进程是唯...

网友评论

    本文标题:探寻iOS内存分配

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