新的自动引用计数机制如何工作?

有人可以简单地向我解释ARC的工作原理吗? 我知道它与垃圾收集不同,但我只是想知道它是如何工作的。

另外,如果ARC在不妨碍性能的情况下执行GC的操作,那么为什么Java使用GC? 为什么它不使用ARC?


每个来到Objective-C的新开发人员都必须学习何时保留,发布和自动释放对象的严格规则。 这些规则甚至指定了隐含从方法返回的对象的保留数的命名约定。 Objective-C中的内存管理一旦将这些规则放在心上并一致地应用它们,就会成为第二性质,但即使是最有经验的Cocoa开发人员也会时不时地出现问题。

通过Clang静态分析器,LLVM开发人员意识到这些规则足够可靠,他们可以构建一个工具来指出代码所需路径内存泄漏和过度释放。

自动引用计数(ARC)是下一个逻辑步骤。 如果编译器可以识别你应该保留和释放对象的位置,为什么不让它为你插入该代码? 刚性,重复的任务是编译器和他们的弟兄们擅长的。 人类忘记事物并犯错,但计算机更加一致。

但是,这并不能让你完全免于担心这些平台上的内存管理。 我在我的答案中描述了需要留意的主要问题(保留周期),这可能需要您稍稍考虑标记弱指针。 然而,与你在ARC中获得的东西相比,这是微不足道的。

与手动内存管理和垃圾收集相比,ARC通过削减编写保留/释放代码的需求,为您提供两全其美的解决方案,但不会在垃圾收集环境中看到暂停和锯齿内存配置文件。 关于垃圾收集在这方面唯一的优点是它处理保留周期的能力以及原子属性分配不昂贵的事实(如此处所讨论的)。 我知道我正在使用ARC实现替换现有的所有Mac GC代码。

至于这是否可以扩展到其他语言,它似乎围绕着Objective-C中的引用计数系统。 将其应用于Java或其他语言可能会很困难,但我对低级别编译器的详细信息不够了解,无法在此处作出明确的声明。 考虑到苹果是LLVM推动这项工作的人,Objective-C将首先出现,除非另一方承诺为此提供大量资源。

这个令人震惊的开发者在WWDC上揭幕,所以人们并没有意识到可以这样做。 随着时间的推移,它可能会出现在其他平台上,但现在它仅限于LLVM和Objective-C。


ARC只是在编译器确定何时调用保留/释放时播放旧保留/释放(MRC)。 与GC系统相比,它将具有更高的性能,更低的内存使用量以及更可预测的性能。

另一方面,ARC(或MRC)不可能使用某些类型的数据结构,而GC可以处理它们。

作为一个例子,如果你有一个名为node的类,并且节点有一个NSArray的子​​节点,并且它的父节点对GC“正常工作”。 使用ARC(以及手动引用计数),您遇到问题。 任何给定的节点都将从它的子节点和其父节点引用。

喜欢:

A -> [B1, B2, B3]
B1 -> A, B2 -> A, B3 -> A

当你使用A时(比如通过局部变量),一切都很好。

当你完成它(和B1 / B2 / B3)时,一个GC系统最终会决定从堆栈和CPU寄存器开始查找所有可以找到的东西。 它永远不会找到A,B1,B2,B3,因此它将最终确定它们并将内存回收到其他对象中。

当你使用ARC或者MRC,并且用A结束时它有一个3的refcount(B1,B2和B3都引用它),而B1 / B2 / B3都将有一个引用计数为1(A的NSArray有一个引用每)。 因此,即使没有任何东西可以使用它们,所有这些对象仍然保持活跃

常见的解决方案是决定其中一个引用需要较弱(不参与引用计数)。 这将适用于某些使用模式,例如,如果仅通过A引用B1 / B2 / B3,但在其他模式下则失败。 例如,如果您有时会坚持B1,并且希望通过父指针爬升并找到答案A.如果您只持有B1,那么A可以(通常会)蒸发,然后取B2和B3用它。

有时候这不是问题,但一些非常有用和自然的处理复杂数据结构的方式很难用于ARC / MRC。

所以ARC针对GC目标的相同问题。 然而,ARC使用更为有限的一组使用模式,然后使用GC,所以如果您使用GC语言(如Java)并将ARC之类的东西嫁接到其上,某些程序将不再工作(或者至少会产生大量废弃的内存,并可能导致严重的交换问题或内存不足或交换空间)。

您也可以说ARC将绩效放在更重要的位置(或者可能是可预测性),而GC则更重视成为一个通用的解决方案。 因此,GC具有较低的可预测CPU /内存需求,并且性能(通常)低于ARC,但可以处理任何使用模式。 ARC对很多很多常见的使用模式都会有很好的效果,但对于一些(有效的!)使用模式,它会崩溃并死亡。


魔法

但更具体地说,ARC通过完成您的代码(具有某些细微差别)来完成工作。 ARC是一种编译时技术,与运行时不同的GC不同,它会对您的性能造成负面影响。 ARC将跟踪对象的引用,并根据常规规则合成保留/释放/自动释放方法。 由于这种ARC可以在不再需要时立即释放,而不是仅仅为了传统而将它们放入自动释放池中。

其他一些改进包括调零弱引用,自动将块复制到堆中,加速全局(自动释放池为6倍!)。

有关这些工作原理的更详细讨论可在ARC的LLVM文档中找到。

链接地址: http://www.djcxy.com/p/19881.html

上一篇: How does the new automatic reference counting mechanism work?

下一篇: Reading a plain text file in Java