为什么Java和Python垃圾回收方法不同?
Python使用引用计数方法来处理对象的生存期。因此,不再有用的对象将立即被摧毁。
但是,在Java中,GC(垃圾回收器)会破坏在特定时间不再使用的对象。
为什么Java选择这种策略,这样做有什么好处?
这比Python方法更好吗?
Python使用引用计数方法来处理对象的生存期。因此,不再有用的对象将立即被摧毁。
但是,在Java中,GC(垃圾回收器)会破坏在特定时间不再使用的对象。
为什么Java选择这种策略,这样做有什么好处?
这比Python方法更好吗?
使用引用计数存在缺点。其中提到最多的是循环引用:假设A引用B,B引用C,C引用B。如果 A 删除对 B 的引用,则 B 和 C 的引用计数仍将为 1,并且不会使用传统引用计数删除。CPython(引用计数不是python本身的一部分,而是其C实现的一部分)使用定期运行的单独垃圾回收例程捕获循环引用...
另一个缺点:引用计数会使执行速度变慢。每次引用和取消引用对象时,解释器/VM 都必须检查计数是否已降至 0(如果已取消分配,则取消分配)。垃圾回收不需要这样做。
此外,垃圾回收可以在单独的线程中完成(尽管它可能有点棘手)。在具有大量 RAM 的计算机上以及仅使用内存的进程中,您可能根本不想执行 GC!在性能方面,参考计数会有点缺点...
实际上,引用计数和 Sun JVM 使用的策略都是不同类型的垃圾回收算法。
有两种广泛的方法来跟踪死对象:跟踪和引用计数。在跟踪中,GC 从“根”(如堆栈引用)开始,并跟踪所有可访问(实时)对象。任何无法到达的东西都被认为是死亡的。在引用计数中,每次修改引用时,所涉及的对象都会更新其计数。引用计数设置为零的任何对象都被视为死项。
对于基本上所有的GC实现,都需要权衡,但跟踪通常适用于高吞吐量(即快速)操作,但具有更长的暂停时间(UI或程序可能会冻结的较大间隙)。引用计数可以在较小的块中运行,但总体上会变慢。这可能意味着冻结较少,但总体性能较差。
此外,参考计数GC需要循环检测器来清理循环中的任何物体,这些物体不会仅被其参考计数捕获。Perl 5在其GC实现中没有周期检测器,并且可能会泄漏循环内存。
还进行了研究,以获得两全其美(低暂停时间,高吞吐量):http://cs.anu.edu.au/~Steve.Blackburn/pubs/papers/urc-oopsla-2003.pdf