iOS内存管理主要有GC标记清除算法和引用计数方法两类:
GC标记清除算法
Garbage Collection,垃圾回收
引用计数方法
回收引用计算为0的对象,减少查找次数;在开发过程中我们应该注意⚠️循环饮用问题,如:外部强引用Block时,Block也会强引用外部的变量,此时可以通过若引用来解决这个问题。
ARC是交由编译器来处理内存管理的,它的效率比较低,以及在ARC还没有出现的时候,用的都是MRC;所以在某些特殊场景还是需要用到MRC的,如:特别需要管理内、化内存的时候;以及项目遗留的老代码是使用MRC来手动管理代码的。
虚拟内存
iOS增加了一个中间层来(也就是虚拟内存)间接访问物理内存,从而解决软件 多程序 多任务 同时运行的问题;
虚拟内存通过映射,将虚拟地址转化为物理地址;
虚拟内存会给每个程序创建一个单独的执行环境,一个独立的虚拟环境,每个程序只能访问自己的地址空间,程序与程序之间被隔离起来,也就是沙盒环境;
每个程序都有自己的进程,进程的内存布局主要有:代码段、数据段、栈、堆组成;如:程序生成的会变代码会放在代码段
,他们具体的布局如下图:
分段
分段就是将进程里连在一起的代码段、数据段、栈、堆分成独立的段;每个段内的空间是连续,但是段与段之间不连续。
分页
分页就是将地址空间切分成固定大小的单元(Virtural Page&Physical Page)。
内存管理方案
- 散列表方式(自旋锁、引用计数表、弱引用表)
- 以及其他两种
MRC(手动引用计数)
用到的几个字段
alloc
分配一个内存空间
retain
使引用计数+1
release
使引用计数-1
retainCount
获取当前对象的引用计数值
autorelease
调用release,-1
dealloc
废除引用对象
ARC(自动引用计数)
- 编译器和runtime自动插入retain和release的结果
- 禁止手动调用retain、release、retainCount、dealloc(可重写,但不能显式调用Super dealloc)
- 有了weak、strong属性关键字
自动释放池
编译器会将@autoreleasepool{}
改写为
void *ctx = objc_autoreleasePoolPush();
{}中的代码
objc_autoreleasePoolPop(ctx);
{} 中的所有对想象都会添加到自动释放池中,pop函数调用之后,{}里面的所有所有对象都会执行release操作,实质上自动释放池是以栈为节点通过双向链表的形式组合而成,并且会在当次runloop将要结束的时候调用AutoreleasePoolPage::pop()。
block内存管理
网友评论