这似乎类似于在Mac上使用Objective-C和其他语言中执行的垃圾回收。 ARC与垃圾回收有何不同?
如我在这里所述,ARC可以同时提供手动内存管理和追踪垃圾回收的优点。它大部分减少了开发人员跟踪Objective-C对象上的手动retain、release和autorelease的需求,同时避免了垃圾回收进程的需要,后者可能会消耗移动设备上有限的资源并导致应用程序偶尔出现停滞。
ARC在编译时插入了所需的保留和释放以进行引用计数,应用了所有Objective-C开发人员多年来必须使用的规则,因此开发人员无需自己管理这些操作。由于保留和释放是在编译时插入的,因此不需要收集器进程不断地扫描内存并删除未被引用的对象。
追踪垃圾回收相对于ARC的一个微小优势是,ARC无法处理保留循环(retain cycles),而追踪垃圾回收可以检测到这些循环。
关于这个话题的一篇很好的文章来自苹果Objective-C邮件列表中的这个帖子,其中Chris Lattner说:
GC相对于ARC的主要优点是它可以回收保留循环。其次,由于“保留”赋值只是一个简单的存储,因此它们是“原子”的。ARC相对于libauto GC具有几个巨大的优势:
- 它对对象进行了确定性(当对象的最后一个strong引用消失时)回收,而GC在“以后某个时间”释放对象。这定义了GC应用程序中可能存在但未暴露的一类微妙错误。
- 由于对象更早地释放,所以ARC的高水位线通常比GC低得多。
- libauto提供了一种脆弱的编程模型,你必须小心,以免丢失写入障碍等。
- 并非所有系统框架都是GC干净的,并且随着它们的演变,这些框架偶尔会出现回归。
- ARC不会遭受虚假根节点。 libauto保守地扫描堆栈,这意味着看起来像指针的整数可以成为对象图的根节点。
- ARC没有任何会启动并停止你的应用程序,导致UI卡顿的东西。 就GC实现而言,libauto相当先进,因为它不会立即停止每个线程,但通常仍然会停止所有UI线程。
我目前正在将我的手动内存管理项目以及使用Objective-C垃圾回收的项目迁移到ARC。在几个Mac应用程序中使用垃圾回收后,我看到将这些项目迁移到ARC中有一些显着优势。
ARC 依靠在编译时“引用”对象,使其在低功率环境下(移动设备)高效。
GC 依靠在运行时“可达”对象,使其在多线程环境下高效。
ARC将代码注入可执行文件中,以便在引用计数未使用的对象上“自动”执行。
GC在运行时工作,它会检测未使用的对象图(并消除保留循环),并在不确定的时间间隔内删除它们。
ARC和垃圾回收有什么不同?
ARC是一种垃圾回收形式。
你可能想问的是“ARC和追踪垃圾回收(如JVM和.NET)之间的区别是什么?”主要区别在于ARC较慢且会泄漏循环。这就是为什么JVM和.NET都使用追踪垃圾收集器的原因。欲了解更多信息,请阅读引用计数和追踪垃圾回收的比较。
简短而明了的答案如下:
Java的GC是运行时进行垃圾回收,而ARC是编译时进行。
GC在运行时引用对象并检查其依赖关系。 而ARC在编译时附加释放、保留和自动释放调用。