【发布时间】:2011-12-14 00:45:52
【问题描述】:
随着 Xcode 4.2 中引入的新的自动引用计数 (ARC),我们不再需要在 Objective-C 中手动管理保留/释放。
这似乎类似于垃圾收集,就像在 Mac 上的 Objective-C 和其他语言中所做的那样。 ARC 与垃圾回收有何不同?
【问题讨论】:
标签: iphone ios garbage-collection automatic-ref-counting
随着 Xcode 4.2 中引入的新的自动引用计数 (ARC),我们不再需要在 Objective-C 中手动管理保留/释放。
这似乎类似于垃圾收集,就像在 Mac 上的 Objective-C 和其他语言中所做的那样。 ARC 与垃圾回收有何不同?
【问题讨论】:
标签: iphone ios garbage-collection automatic-ref-counting
ARC 依赖于编译时“引用”对象,这使其在低功耗模式环境(移动设备)中高效。
GC 依赖于基于运行时的“可达”对象,这使其在多线程环境中高效。
ARC 将代码注入到可执行文件中,以根据其引用计数“自动”在未使用的对象上执行。
GC 在运行时工作,因为它会检测未使用的对象图(将消除保留周期)并在不确定的时间间隔内将其删除
【讨论】:
正如我在回答 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 相比的优势:
- 它具有确定性的对象回收(当对该对象的最后一个强引用消失时),其中 GC 有时会释放一个对象 稍后”。这定义了可能存在于 GC 中的一类细微错误 由于收集器未触发“在 错误的窗口”。
- ARC 的高水位线通常比 GC 低得多,因为对象释放得更快。
- libauto 提供了一个脆弱的编程模型,你必须小心不要丢失写屏障等。
- 并非所有的系统框架都是 GC 干净的,而且这些框架偶尔会随着它们的发展而退化。
- ARC 不受假根的影响。 libauto 保守地扫描堆栈,这意味着看起来像指针的整数可以根 对象图。
- ARC 没有任何东西可以启动和停止您的应用程序,从而导致 UI 卡顿。就 GC 实现而言,libauto 相当先进 go 因为它不会立即停止每个线程,但它仍然会 通常最终会停止所有 UI 线程。
我目前正在将我的手动内存管理项目以及使用 Objective-C 垃圾收集的项目迁移到 ARC。在几个 Mac 应用程序中使用垃圾收集一段时间后,我发现将这些项目迁移到 ARC 有一些显着优势。
【讨论】:
ARC 与垃圾回收有何不同?
ARC 是垃圾回收的一种形式。
您可能的意思是“ARC 和跟踪垃圾收集(如 JVM 和 .NET)有什么区别?”。主要区别在于 ARC 速度较慢且泄漏周期。这就是 JVM 和 .NET 都使用跟踪垃圾收集器的原因。更多信息请阅读How do reference counting and tracing garbage collection compare?。
【讨论】:
简短而甜蜜的答案如下:
java的GC是Runtime,ARC是compile time。
GC 在运行时引用对象并检查对象运行时的依赖关系。 而 ARC 在编译时附加 release、retain、autorelease 调用。
【讨论】: