内存管理、ARC、MRC

内存中的五大区域:
栈区,堆区,BBS段,数据段和代码段,其中除了堆区以外,其他区域的内存管理由系统自行回收
OC对象是存储在堆区的,所以OC的内存管理主要是对”堆区中的OC对象”进行管理
 
内存管理中的几个概念:
->引用计算器:既retainCount,每个OC对象内部都有1个8字节空间用来存储retainCount,表示有多少”人”正在使用;
对象刚被创建时,默认计数值就为1,当计数值为0时,系统会自动调用dealloc方法将对象销毁
引用计数器的用法:给对象发送相应的技术操作来改变计数器的值
     retain消息:使计数器+1
     release消息:使计数器-1
      retainCount消息:得到当前当前retainCount的值
->野指针:没有初始化的指针变量
->僵尸对象:指一个对象已经被回收,但其数据还存在内存中
僵尸对象有可能可以访问,也有可能不能访问,取决于所占用空间是否已被重新分配.然而,对象一旦被回收就不该再被访问

->内存泄露:指对象没有在该回收的时候被回收,而是一直驻留在内存中,直到程序结束的时候才被释放

内存管理的分类:
->MRC:Manual Reference Counting,既手动内存管理对引用计数器的操作全由程序员亲自完成
->ARC:Automatic Reference Counting,既自动内存管理
->自动释放池(autorelease):存储在自动释放池的对象,在自动释放池销毁时,会自动调用该对象的release方法,故将对象存储在自动释放池中,就不需要再写release
 
nonatomic,retain,weak,strong用法
strong是ARC引用的,一般可看做retain
weak比assign多了一个功能,当对象消失后自动把指针变成nil,好处不言而喻。
nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能
__unsafe_unretained 声明一个弱应用,但是不会自动nil化,也就是说,如果所指向的内存区域被释放了,这个指针就是一个野指针了。
__autoreleasing 用来修饰一个函数的参数,这个参数会在函数返回的时候被自动释放。
 

面试题:简单介绍 ARC 以及 ARC 实现的原理。

考查点

ARC 是苹果在 WWDC 2011 提出来的技术,因此很多新入行的同学可能对此技术细节并不熟悉。但是,虽然 ARC 极大地简化了我们的内存管理工作,但是引用计数这种内存管理方案如果不被理解,那么就无法处理好那些棘手的循环引用问题。所以,这道面试题其实是考查同学对于 iOS 程序内存管理的理解深度。

答案

自动的引用计数(Automatic Reference Count 简称 ARC),是苹果在 WWDC 2011 年大会上提出的用于内存管理的技术。

引用计数(Reference Count)是一个简单而有效的管理对象生命周期的方式。当我们创建一个新对象的时候,它的引用计数为 1,当有一个新的指针指向这个对象时,我们将其引用计数加 1,当某个指针不再指向这个对象是,我们将其引用计数减 1,当对象的引用计数变为 0 时,说明这个对象不再被任何指针指向了,这个时候我们就可以将对象销毁,回收内存。

引用计数这种内存管理方式虽然简单,但是手工写大量的操作引用计数的代码不但繁琐,而且容易被遗漏。于是苹果在 2011 年引入了 ARC。ARC 顾名思义,是自动帮我们填写引用计数代码的一项功能

ARC 的想法来源于苹果在早期设计 Xcode 的 Analyzer 的时候,发现编译器在编译时可以帮助大家发现很多内存管理中的问题。后来苹果就想,能不能干脆编译器在编译的时候,把内存管理的代码都自动补上,带着这种想法,苹果修改了一些内存管理代码的书写方式(例如引入了 @autoreleasepool 关键字)后,在 Xcode 中实现了这个想法。

ARC 的工作原理大致是这样:当我们编译源码的时候,编译器会分析源码中每个对象的生命周期,然后基于这些对象的生命周期,来添加相应的引用计数操作代码。所以,ARC 是工作在编译期的一种技术方案,这样的好处是:

  1. 编译之后,ARC 与非 ARC 代码是没有什么差别的,所以二者可以在源码中共存。实际上,你可以通过编译参数 -fno-objc-arc 来关闭部分源代码的 ARC 特性。

  2. 相对于垃圾回收这类内存管理方案,ARC 不会带来运行时的额外开销,所以对于应用的运行效率不会有影响。相反,由于 ARC 能够深度分析每一个对象的生命周期,它能够做到比人工管理引用计数更加高效。例如在一个函数中,对一个对象刚开始有一个引用计数 +1的操作,之后又紧接着有一个 -1 的操作,那么编译器就可以把这两个操作都优化掉。

但是也有人认为,ARC 也附带有运行期的一些机制来使 ARC 能够更好的工作,他们主要是指 weak 关键字。weak 变量能够在引用计数为 0 时被自动设置成 nil,显然是有运行时逻辑在工作的。我通常并没有把这个算在 ARC 的概念当中,当然,这更多是一个概念或定义上的分歧,因为除开 weak 逻辑之外,ARC 核心的代码都是在编译期填充的。

 

posted on 2017-02-20 20:39  摩羯小伟  阅读(128)  评论(0编辑  收藏  举报

导航