李洪强iOS经典面试题31-解释垃圾回收的原理

问题

我们知道,Android 手机通常使用 Java 来开发,而 Java 是使用垃圾回收这种内存管理方式。 那么,ARC 和垃圾回收对比,有什么优点和缺点?

考查点

此题其实是考查大家的知识面,虽然做 iOS 开发并不需要用到垃圾回收这种内存管理机制。但是垃圾回收被使用得非常普遍,不但有 Java,还包括 JavaScript, C#,Go 等语言。

如果两个候选人,一个人只会 iOS 开发,另一个人不但会 iOS 开发,对别的语言或技术也有兴趣了解,那我通常更倾向于后者。而且事实常常是,由于后者对计算机兴趣更浓,他在 iOS 上也通常专研得比前者更多。

垃圾回收简介

作为 iOS 开发者,了解一下这个世界上除了 ARC 之外最流行的内存管理方式,还是挺有价值的。所以我尽量简单给大家介绍一下。

垃圾回收(Garbage Collection,简称 GC)这种内存管理机制最早由图灵奖获得者 John McCarthy 在 1959 年提出,垃圾回收的理论主要基于一个事实:大部分的对象的生命期都很短。

所以,GC 将内存中的对象主要分成两个区域:Young 区和 Old 区。对象先在 Young 区被创建,然后如果经过一段时间还存活着,则被移动到 Old 区。(其实还有一个 Perm 区,但是内存回收算法通常不涉及这个区域)

Young 区和 Old 区因为对象的特点不一样,所以采用了两种完全不同的内存回收算法。

Young 区的对象因为大部分生命期都很短,每次回收之后只有少部分能够存活,所以采用的算法叫 Copying 算法,简单说来就是直接把活着的对象复制到另一个地方。Young 区内部又分成了三块区域:Eden 区 , From 区 , To 区。每次执行 Copying 算法时,即将存活的对象从 Eden 区和 From 区复制到 To 区,然后交换 From 区和 To 区的名字(即 From 区变成 To 区,To 区变成 From 区)。

Old 区的对象因为都是存活下来的老司机了,所以如果用 Copying 算法的话,很可能 90% 的对象都得复制一遍了,不划算啊!所以 Old 区的回收算法叫 Mark-Sweep 算法。简单来说,就是只是把不用的对象先标记(Mark)出来,然后回收(Sweep),活着的对象就不动它了。因为大部分对象都活着,所以回收下来的对象并不多。但是这个算法会有一个问题:它会产生内存碎片,所以它一般还会带有整理内存碎片的逻辑,在算法中叫做 Compact。如何整理呢?早年用过 Windows 的硬盘碎片整理程序的朋友可能能理解,其实就是把对象插到这些空的位置里。这里面还涉及很多优化的细节,我就不一一展开了。

讲完主要的算法,接下来 GC 需要解决的问题就只剩下如何找出需要回收的垃圾对象了。为了避免 ARC 解决不了的循环引用问题,GC 引入了一个叫做「可达性」的概念,应用这个概念,即使是有循环引用的垃圾对象,也可以被回收掉。下面就给大家介绍一下这个概念。

当 GC 工作时,GC 认为当前的一些对象是有效的,这些对象包括:全局变量,栈里面的变量等,然后 GC 从这些变量出发,去标记这些变量「可达」的其它变量,这个标记是一个递归的过程,最后就像从树根的内存对象开始,把所有的树枝和树叶都记成可达的了。那除了这些「可达」的变量,别的变量就都需要被回收了。

听起来很牛逼对不对?那为什么苹果不用呢?实际上苹果在 OS X 10.5 的时候还真用了,不过在 10.7 的时候把 GC 换成了 ARC。那么,GC 有什么问题让苹果不能忍,这就是:垃圾回收的时候,整个程序需要暂停,英文把这个过程叫做:Stop the World。所以说,你知道 Android 手机有时候为什么会卡吧,GC 就相当于春运的最后一天返城高峰。当所有的对象都需要一起回收时,那种体验肯定是当时还在世的乔布斯忍受不了的。

看看下面这幅漫画,真实地展现出 GC 最尴尬的情况(漫画中提到的 Full GC,就是指执行 Old 区的内存回收):

当然,事实上经过多年的发展,GC 的回收算法一直在被优化,人们想了各种办法来优化暂停的时间,所以情况并没有那么糟糕。

答案

ARC 相对于 GC 的优点:

  1. ARC 工作在编译期,在运行时没有额外开销。

  2. ARC 的内存回收是平稳进行的,对象不被使用时会立即被回收。而 GC 的内存回收是一阵一阵的,回收时需要暂停程序,会有一定的卡顿。

ARC 相对于 GC 的缺点:

  1. GC 真的是太简单了,基本上完全不用处理内存管理问题,而 ARC 还是需要处理类似循环引用这种内存管理问题。

  2. GC 一类的语言相对来说学习起来更简单。

在 Wikipedia 上,还有更详细的优缺点对比,感兴趣的同学可以深入学习。

李洪强iOS经典面试题31-解释垃圾回收的原理的更多相关文章

  1. 李洪强iOS经典面试题37-解释垃圾回收的原理

    李洪强iOS经典面试题37-解释垃圾回收的原理   问题 我们知道,Android 手机通常使用 Java 来开发,而 Java 是使用垃圾回收这种内存管理方式. 那么,ARC 和垃圾回收对比,有什么 ...

  2. 李洪强iOS经典面试题下

    李洪强iOS经典面试题下 21. 下面的代码输出什么? @implementation Son : Father - (id)init { self = [super init]; if (self) ...

  3. 李洪强iOS经典面试题156 - Runtime详解(面试必备)

    李洪强iOS经典面试题156 - Runtime详解(面试必备)   一.runtime简介 RunTime简称运行时.OC就是运行时机制,也就是在运行时候的一些机制,其中最主要的是消息机制. 对于C ...

  4. 李洪强iOS经典面试题155 - const,static,extern详解(面试必备)

    李洪强iOS经典面试题155 - const,static,extern详解(面试必备) 一.const与宏的区别(面试题): const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽 ...

  5. 李洪强iOS经典面试题154- 通知与推送

    李洪强iOS经典面试题154- 通知与推送   通知与推送 本地通知和远程推送通知对基本概念和用法? image 本地通知和远程推送通知都可以向不在前台运行的应用发送消息,这种消息既可能是即将发生的事 ...

  6. 李洪强iOS经典面试题153- 补充

    李洪强iOS经典面试题153- 补充   补充 有空就来解决几个问题,已经懒癌晚期没救了... UML 统一建模语言(UML,UnifiedModelingLanguage)是面向对象软件的标准化建模 ...

  7. 李洪强iOS经典面试题147-WebView与JS交互

    李洪强iOS经典面试题147-WebView与JS交互   WebView与JS交互 iOS中调用HTML 1. 加载网页 NSURL *url = [[NSBundle mainBundle] UR ...

  8. 李洪强iOS经典面试题144-数据存储

    李洪强iOS经典面试题144-数据存储   数据存储 sqlite中插入特殊字符的方法和接收到处理方法. 除'其他的都是在特殊字符前面加"/",而 ' -> '' .方法:k ...

  9. 李洪强iOS经典面试题143-绘图与动画

    李洪强iOS经典面试题143-绘图与动画   绘图与动画 CAAnimation的层级结构 CAPropertyAnimation是CAAnimation的子类,也是个抽象类,要想创建动画对象,应该使 ...

随机推荐

  1. tile xml格式

    <map> version: The TMX format version, generally 1.0. orientation: Map orientation. Tiled supp ...

  2. 统计中的t检验

    1.什么情况下,应用t检验 1. 已知总体的均值m,或者我们假设了一个总体均值m: 2. 我们知道样本的个数n,样本的的方差var,样本的均值m: 3. 我们假设总体,或者样本都是服从正太分布的. 2 ...

  3. Object.keys()的简单理解

    1.对象的话返回属性名 var obj = {'a':'123','b':'345'}; console.log(Object.keys(obj)); //['a','b'] var obj1 = { ...

  4. android sdk下载SDK Platform失败记录

    在使用android sdk manager下载的时候会遇到 下载完毕后,你可能会出现如下图一样的错误,就算重复尝试多次依然无法正常安装 Downloading SDK Platform Androi ...

  5. 解决html视频播放只有声音没有图像的办法

    HTML5中并没有指定视频解码器,它留给了浏览器来决定. MP4有四种编码格式(MPEG4(DivX),MPEG4(Xvid),AVC(H264),HEVC(H265)): 只有使用AVC(H264) ...

  6. Spark详解

    原文连接 http://xiguada.org/spark/ Spark概述 当前,MapReduce编程模型已经成为主流的分布式编程模型,它极大地方便了编程人员在不会分布式并行编程的情况下,将自己的 ...

  7. js 实现存储Map 结构的数据

    <script type="text/javascript"> function Map() { var struct = function(key, value) { ...

  8. centos 7安装 navicat

    下载地址: http://download.navicat.com/download/navicat111_mysql_en.tar.gz 下载后copy到指定安装文件夹 [hcr@localhost ...

  9. SOA初探

    背景 曾今SOA的概念犹如今日“云计算.大数据”一样,被炒得火热,不少企业便纷纷响应,并宣称会拥抱和实施SOA.而事实上,业界出现了两种极端:一种是由于各类文章和书籍关于SOA的描述往往太过抽象,再加 ...

  10. swift 常用第三方库

    1.Network: Alamofire:著名的AFNetworking网络基础库Swift版  -https://github.com/Alamofire/Alamofire SwiftyJSON: ...