Objective-C自动引用计数和垃圾收集有什么区别?

时间:2011-10-24 10:36:11

标签: iphone ios garbage-collection automatic-ref-counting

使用Xcode 4.2中引入的新自动引用计数(ARC),我们不再需要在Objective-C中手动管理保留/释放。

这看起来类似于垃圾收集,就像Mac上的Objective-C和其他语言一样。 ARC如何与垃圾收集不同?

4 个答案:

答案 0 :(得分:63)

正如我在回答here中所描述的那样,ARC可以提供最佳的手动内存管理和跟踪垃圾回收。它主要消除了开发人员跟踪Objective-C对象上的手动保留,发布和自动释放的需要,同时避免了垃圾收集器进程的需要,这可能会耗尽移动设备上的有限资源并导致正在运行的应用程序中出现断断续续的异常情况

ARC通过应用所有Objective-C开发人员多年来必须使用的规则,在编译时插入引用计数所需的相应保留和释放。这使开发人员不必自己管理它。因为保留和释放是在编译时插入的,所以不需要收集器进程来连续扫描内存并删除未引用的对象。

通过ARC跟踪垃圾收集的一个小优点是ARC will not deal with retain cycles for you,其中跟踪垃圾收集可以选择这些。

关于这个主题的精彩读物来自this thread on Apple's Objective-C mailing list,其中Chris Lattner这样说:

  

GC相对于ARC的主要优点是它可以收集保留   周期。第二个优点是“保留”的任务是   “原子”因为它们是一个简单的商店。 ARC有几个大的   优于libauto GC的优势:

     
      
  1. 它具有确定性的对象回收(当对象的最后一个强引用消失时)GC在某个时间释放对象   后来“。这定义了GC中可能存在的一类微妙的错误   未公开的应用程序,因为收集器不会触发“   越野车窗口“。
  2.   
  3. ARC的高水位标记通常远低于GC,因为物体会更快释放。
  4.   
  5. libauto提供了一个脆弱的编程模型,你必须小心不要丢失写入障碍等。
  6.   
  7. 并非所有的系统框架都是GC干净的,并且框架在进化时偶尔会回归。
  8.   
  9. ARC不会遭受假根。 libauto保守地扫描堆栈,这意味着看起来像指针的整数可以root   对象图。
  10.   
  11. ARC没有任何内容可以启动并停止您的应用,导致UI口吃。就GC实现而言,libauto非常先进   因为它没有立即停止每个线程,但它仍然存在   通常最终停止所有UI线程。
  12.   

我目前正在将手动内存管理项目以及使用Objective-C垃圾回收的项目迁移到ARC。在几个Mac应用程序中使用垃圾收集一段时间后,我发现将这些项目移动到ARC有一些显着的优势。

答案 1 :(得分:12)

ARC 依赖于编译时间"引用"使其在低功耗模式环境(移动设备)中高效的对象。

GC 依赖于基于运行时的"可达"使其在多线程环境中高效的对象。

操作

ARC将代码注入要执行的可执行文件"自动"在未使用的对象上,取决于它们的引用计数。

GC在运行时工作,因为它将检测未使用的对象图(将消除保留周期)并在不确定的时间间隔内删除它们

自动参考计数的优点

  • 对象成为时的实时,确定性破坏 未使用。
  • 无后台处理。

垃圾收集的优点

  • GC可以清理整个对象图,包括保留周期。
  • GC在后台进行,因此减少了内存管理工作 作为常规申请流程的一部分。

自动参考计数的缺点

  • ARC无法自动处理保留周期。

垃圾收集的缺点

  • 因为GC在后台发生,所以对象的确切时间范围 发布尚未确定。
  • 当GC发生时,应用程序中的其他线程可能是 暂时搁置。

答案 2 :(得分:7)

  

ARC与垃圾收集有何不同?

ARC是垃圾收集的一种形式。

你可能意味着“ARC和跟踪垃圾收集(如JVM和.NET)之间有什么区别?”。主要区别在于ARC较慢且泄漏周期。这就是JVM和.NET都使用跟踪垃圾收集器的原因。有关详细信息,请阅读How do reference counting and tracing garbage collection compare?

答案 3 :(得分:-6)

简短而甜蜜的回答如下:

java的GC是Runtime,而ARC是编译时。

GC在运行时引用了对象,并检查对象运行时的依赖关系。    ARC在编译时附加发布,保留,自动释放调用。