Java 为什么不';大多数JVM GC是否使用引用计数?

Java 为什么不';大多数JVM GC是否使用引用计数?,java,garbage-collection,jvm,Java,Garbage Collection,Jvm,为什么他们不需要它们呢?如果有人决定实现一个使用它们的虚拟机,他们可能会面临什么问题?引用计数会由于周期性引用而导致内存泄漏。假设您有一个简单的“node”对象,该对象具有对另一个节点的引用,并假设您将其引用设置为自身。该对象的引用计数将始终为1,即使全局变量或堆栈变量没有对其进行句柄,因此它将永远不会被垃圾收集,并且是泄漏的内存。这是一个微不足道的例子,但任何循环引用都会有相同的问题 当然,可以检测循环引用,但这样做的开销可能会增加足够的复杂性,使得其他GC方法更具吸引力。 计数引用必须在对

为什么他们不需要它们呢?如果有人决定实现一个使用它们的虚拟机,他们可能会面临什么问题?

引用计数会由于周期性引用而导致内存泄漏。假设您有一个简单的“node”对象,该对象具有对另一个节点的引用,并假设您将其引用设置为自身。该对象的引用计数将始终为1,即使全局变量或堆栈变量没有对其进行句柄,因此它将永远不会被垃圾收集,并且是泄漏的内存。这是一个微不足道的例子,但任何循环引用都会有相同的问题

当然,可以检测循环引用,但这样做的开销可能会增加足够的复杂性,使得其他GC方法更具吸引力。

  • 计数引用必须在对象外部进行。
  • 计算引用的速度很慢。处理循环引用会更慢,但这不是不可能的。还是慢。
  • 计数引用实际上非常慢,因为它必须使用CAS+循环
  • 不计算引用更容易实现,而且速度更快,特别是使用一些操作系统内存页技巧。
  • 引用计数可以通过转义分析完全删除,前提是对象不转义。

    您可以使用“真正的”GC来增加refcounting,因为生成的垃圾中只有一部分(通常很小)包含循环,因此自然必须减少运行次数。另一个因素是速度-一个聪明、优化的GC可以比refcounting做得更好,特别是在存在线程的情况下(由于锁定,增加/减少refcounts的成本更高)。delnan,将您的评论作为答案发布,我将选择它作为答案answer@delnan不仅成本更高,Java线程使得重新计数实际上是不可能的。由于每个线程都可以自由地将对象的副本保留在自己的内存区域中,并在空闲时将它们写回主区域,因此引用计数很快就会变得不一致。@biziclop,请确保可以根据需要发布对象并保留引用计数,但使用CAS/loop进行引用计数将是愚蠢的。因此,在多线程环境中,整体ref.counting只是一种惩罚。b/c ref count比copy慢