参考计数GC与跟踪GC是语言属性还是实现属性?


9

有时我们会听到“ Swift不执行经典(跟踪)GC,而是使用ARC。”

但是我不确定Swift语义中是否有需要引用计数的内容。似乎可以构建自己的Swift编译器和运行时以使用跟踪GC。

那么Swift的“引用计数”到底是什么?苹果的实现还是语言本身?语言或库中是否有某些部分强烈支持ARC,因此我们可以为语言本身使用该标签?

Answers:


9

Swift 保证一旦删除了对对象的最后一个引用,该对象将被取消初始化,并且deinit代码将立即运行。

无法通过GC获得这种保证-至少在不牺牲性能的情况下。标准GC机制仅确保deinit代码最终得以运行,例如在下一个GC周期。对于精确的语义,您需要在某处引用计数。


3
嗯,所以deinitas关键字的存在及其关联的语义确实是使引用在语言(而不是实现领域)中正确计数的事物。
雷·托尔

2
什么都不会阻止GCed运行时在释放某些对象时检查不可达的对象。效率极低。
拉斐尔

@Raphael编辑为在这一点上更加精确。

3

chi已回答了有关swift的特定问题,此答案回答了标题中较笼统的问题。

参考计数GC与跟踪GC是语言属性还是实现属性?

参考计数GC和跟踪GC为程序员提供了不同的保证。

引用计数可在程序流中破坏对象的位置提供确定​​性,如果对象拥有必须快速释放的稀缺资源,这可能很重要。另一方面,它不能处理“强”引用的循环。

取决于单个语言的规范,如果可以保证有任何特征,那么哪种选择对兼容的实现可用。


4
也可以将refcount和GC结合使用。然后,该语言可以证明对象在没有被引用时就立即执行其析构函数(这意味着以一种或另一种形式进行引用计数),并且引用周期最终将被破坏(这意味着某种形式的GC)。或者,该实现可以在语言不能保证运行析构函数的时候执行此操作(Python及其引用实现就是IIRC),在这种情况下它将是实现属性。
吉尔斯(Gilles)'所以

1

您可以采用称为Swift的语言,并将其重命名为“ Swift with ARC”。然后,您可以使用完全相同的语法创建一种名为“ Swift with GC”的新语言,但是对对象何时被释放的保证较少。

在带有ARC的Swift中,一旦引用计数为0,对象就会消失。使用垃圾回收,只要您有一个弱引用,就可以将该弱引用分配给强引用以“恢复”对象。(在Swift中,一旦引用计数为0,则弱引用为nil);那是一个主要的区别。

当然,带有ARC的Swift可以保证杀死最后一个引用计数将立即释放该对象。例如,您可能具有FileWriter类,在该类中,不允许您同时有两个实例写入同一文件。在带有ARC的Swift中,您可以说oldWriter = nil; newWriter = FileWriter(...),您将知道仅在删除旧FileWriter之后才创建新FileWriter(除非您保留了另一个引用);在带有GC的Swift中这是行不通的。

另一个区别是,在“快速与ARC”,即仅通过强引用循环引用,但实际上不是可达到的对象,被保证为不释放。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.