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

 

问题

我们知道,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经典面试题37-解释垃圾回收的原理的更多相关文章

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

    李洪强iOS经典面试题31-解释垃圾回收的原理 问题 我们知道,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. Webharvest网络爬虫应用总结,web-harvest 编写脚本 读取 百度 博客 实例

      Webharvest网络爬虫应用总结 Web-Harvest是一个Java开源Web数据抽取工具.它能够收集指定的Web页面并从这些页面中提取有用的数据.其实现原理是,根据预先定义的配置文件用ht ...

  2. QT在windows下的安装与配置

    先了解Qt: Qt一直以来,分为商业.开源两个版本,商业版本为用户提供了二级制的动态库,直接安装既可以使用,但是需要花钱购买license,而开源版本则遵守GPL协议,提供了源码,用户需要自行编译,才 ...

  3. Effective C++ 条款 50:了解new和delete的合理替换时机

    (一) 为什么有人想要替换operator new 和 operator delete呢?三个常见的理由: (1)用来检測运用上的错误. (2)为了强化效果. (3)为了收集使用上的统计数据. (二) ...

  4. Tapable 0.2.8 入门

    [原文:Tapable 0.2.8 入门] tapable是webpack的核心框架(4.0以上版本的API已经发生了变化),是一个基于事件流的框架,或者叫做发布订阅模式,或观察者模式,webpack ...

  5. <The Art of Readable Code> 笔记一

    第1章  代码应易理解 (Code should be easy to understand) 基本原则:好的代码,能够减少 “别人” 理解它的时间. “别人” 不仅指的是 “其它人”,也可能是 “以 ...

  6. Android 使用ORMLite 操作数据库

    参考:http://blog.csdn.net/cjjky/article/details/7096987 ormlite 方法查询:http://ormlite.com/javadoc/ormlit ...

  7. 黑马程序员:多线程Socket

    ---------------------- ASP.Net+Android+IOS开发..Net培训.期待与您交流! ----------------------- 一.Socket一般应用模式(服 ...

  8. Ext.encode 与 Ext.decode .

    Ext.encode( Mixed o ) : String: json对象转换json字符串 Ext.decode( String json ) : Object: json字符串转换json对象 ...

  9. GridLayout with span

    Widgets can span multiple columns or rows in a grid. In the next example we illustrate this. #!/usr/ ...

  10. 浅析CentOS和RedHat Linux的区别(转)

    CentOS的简介 CentOS是Community ENTerprise Operating System的简称,我们有很多人叫它社区企业操作系统,不管你怎么叫它,它都是Linux操作系统的一个发行 ...