iOS中的内存管理

04/12/2018 08:47 上午 posted in  apple

既然是内存管理,首先要知道那么内存是用来干什么的?内存具体管理的东西是什么?当然这些东西基本都是常识了,内存当然是用来存储数据的,内存要管理的东西简单的说也就是如何将数据存储到内存中(比如说我们的声明变量就可以将数据存储到内存中),其次存储到内存中的数据怎样释放,什么时候释放,这都是内存管理需要来关心的.

正文:

1.内存中的五大区域

内存分为5个区域,分别指的是----->栈区/堆区/BSS段/数据段/代码段

栈:存储局部变量,当其作用域执行完毕之后,就会被系统立即收回

堆:存储OC对象,手动申请的字节空间,需要调用free来释放

BSS段:未初始化的全局变量和静态变量,一旦初始化就会从BSS段中回收掉,转存到数据段中

数据段:存储已经初始化的全局变量和静态变量,以及常量数据,直到结束程序时才会被立即收回

代码段:代码,直到结束程序时才会被立即收回

2.OC中堆区存储对象的特点

除了堆区,其他区域的中存储的数据,都是又系统自动释放的

堆区中的OC对象,是不会自动释放的,如果不主动释放,那么将在程序结束的时候才去释放

3.引用计数器

首先简单来说一下,每一个OC对象都有一个属性,叫做retainCount,翻译过来也就是引用计数器,类型为unsigned long,占据8个字节,每一个对象负责维护对象所引用的记数值,当一个新的引用指向对象,那么这个对象的引用值增加1,当我们新创建出一个对象的时候这个对象的引用计数器的值默认为1,当这个对象被少一次引用的时候那么就先让这个对象的引用记数值减1,当这个对象所引用的记数值为0的时候,代表这个对象没有被使用,这时系统会自动回收掉此对象,回收这个对象的同时自动调用这个对象的dealloc方法

控制规则:

为对象发送一条retain消息,那么对象的引用计数器的值就会+1

为对象发送一条release消息,那么对象的引用计数器的值就会-1

为对象发送一条retainCount消息,那么就可以得到这个对象的引用计数器的值

4.内存管理的分类

MRC:Manual Reference Counting 手动引用计数器,需要我们手动管理对象引用计数器的值

ARC:Autimatic Reference Counting 自动引用计数器,系统自动的改变对象引用计数器的值(iOS5之后),ARC是基于MRC的

5.内存管理基本原则

新创建一个对象,这个对象的引用计数器的值为1,有对象的创建,就需要匹配一个release

是谁来负责retain的,谁就要负责release,使用的时候retain,不是用的时候release

retain的次数要和release次数想匹配,有加有减,做到平衡

6.野指针

在C中,声明一个指针变量,没有为这个指针变量初始化,那么这个指针变量的值也就是一个垃圾值,指针指向随机的一块空间,那么我们叫做野指针

在OC中,一个指针指向的对象被释放了,那么这个指针叫野指针

7.对象的回收

对象所占用的字节空间,分配给别人使用,系统未分配这块空间被别人使用之前,这个对象的数据仍然处在内存中

8.僵尸对象

已经被收回但是这个对象的数据仍然处在内存中,像这样的对象叫做僵尸对象

僵尸对象有可能可以访问也有可能不可以访问,当僵尸对象所占的内存空间还没有分配给别人使用的时候,这个数据的对象其实仍然存在,通过指针仍然可以找到这个对象,所以说这个时候僵尸对象还可以被访问,当这个僵尸对象已经分配给别人使用的时候,这个对象就不存在了,这个时候不可以被访问

注意:一旦一个对象成为僵尸对象之后,这个对象无论如何都不应该被使用,无论有没有分配给别人使用,都不能用!且不可以复活!

9.避免内存泄漏

有对象的创建,就必须要匹配一个release,retain和release的次数要匹配,不要随便为一个指针赋值为nil,除非这个指针是野指针,在方法中不要随意对传入的对象进行retain

当我们通过野指针去访问僵尸对象的时候会报错,为了避免报错当一个指针成为野指针后,为这个指针赋值为nil

FROM:https://blog.csdn.net/oboe_b/article/details/78140027