Python的GC(垃圾回收)引用计数和Objective-C的ARC有什么区别?

4
我正在阅读有关各种语言的内存管理的文章,其中提到Objective-C没有托管内存,因为它会导致移动应用程序的用户体验出现中断。
我知道ARC无法处理循环引用,而Python的GC可以。我知道ARC根本不是垃圾收集器,因此它不会停止主程序的执行来执行内存管理。
Python是否可以使用混合方法?同时采取一些ARC的优点,并在较短的时间内(或较短的时间内)运行GC,以便仍然能够处理循环引用?
或者Python社区是否尝试过类似的事情?
编辑:我知道Python使用引用计数,但据我所知,当引用计数为0的对象并不会立即从内存中删除(这是ARC的做法)。我想知道立即释放该对象占用的内存是否可以使Python更适用于低内存环境,并且因为在这种情况下GC可能运行得更少,它会导致较少的线程中断。两件事对于移动应用程序来说都是理想的,因为它们可以提高用户体验。

请参见https://dev59.com/uGox5IYBdhLWcg3wpV7F。 - dstromberg
那个链接没有帮助。我知道它使用 RC 和标记-清除技术,但是当引用计数降至0时,对象并不会立即释放,对吧? - Gabriel
1个回答

7
据我所知,Objective-C的ARC(自动引用计数)最终提供的与CPython的引用计数相同,只是没有循环引用处理。ARC仅是一个新的花哨名称,意味着Objective-C编译器会自动插入引用计数代码,而不是程序员手动操作。

为了回答这个问题,我们假设CPython可以用Objective-C重写(这是不现实的)。如果使用ARC而不是显式引用计数,则会得到以下结果:

  • 更简单的代码。

  • 无循环收集。

  • 保证正确的代码。CPython中有一些已知的问题,可能会导致在某些极端情况下崩溃;其中一些基于Lib/test/crashers/

  • 稍微慢一点的代码。事实上,编译器通常不如人类聪明,无法找到我们实际上不需要操作引用计数的情况。

作为PyPy开发人员,我可以报告自己的经验:我们曾经尝试过在编译期间自动插入引用计数代码。然而,我们放弃了这种方法,因为没有高级优化,您会得到非常慢的代码。相反,我们现在使用一些简单的“真正”的垃圾收集(GC)系统;它比CPython的引用计数甚至更快。因此,我对编译器制造商的建议是,如果您想要一个可以自动插入必要代码的编译器,最好使用任何一个更好的GC之一。不过,据我所知,LLVM在这方面的支持仍然几乎为零。


正确性是无可挑剔的,但性能评估可能有些不准确。纯 ARC 代码比正确编写的 MRR 代码少使用一些 retain/release/autorelease 调用。 - bbum
神奇。除非您提供解释,否则我认为这是不可能的。 :-) - Armin Rigo
在MRR中,需要一个工厂方法返回一个autorelease的对象,调用者需要retain它(如果需要的话)。而在ARC中,那个autorelease是不必要的,如果对象没有被保留,编译器会在调用方侧面发出一个release。但是这只是编译器如何优化ARC代码方式之一,远远超出了MRR,并且没有GC的开销。请注意,OS X中的Objective-C垃圾收集器比MRR提供更快的运行时环境(我从未将GC与ARC进行过比较,但目前来看,对于大多数现实世界的应用程序,GC可能仍然比ARC更快...至少目前是这样)。 - bbum
@bbum:不确定您所说的MRR是什么意思,但它可能与CPython的手动引用计数有所不同。后者不是以“autorelease”和“retain”为基础表达的。无论如何,我不明白为什么人类无法手动编码与ARC编译器生成的行为相同(在某些情况下更聪明)。我会坚持我的“需要参考”的评论。 - Armin Rigo
那么你就跑题了。 - Armin Rigo
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接