为什么大多数JVM gcs都不使用refcounts?

Dus*_*etz 9 java garbage-collection jvm

他们为什么不需要它们,如果某人决定实施使用它们的虚拟机,他们可能面临哪些问题?

mae*_*ics 13

由于循环引用,引用计数会受到内存泄漏的影响.想象一下,你有一个简单的"节点"对象,它有一个对另一个节点的引用,并假设你设置它自己的引用.即使没有来自全局变量或堆栈变量的句柄,该对象的引用计数也将始终为1,因此它永远不会被垃圾回收并且是泄漏的内存.这是一个简单的例子,但任何循环引用都会有同样的问题.

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

  • 您可以使用"真正的"GC来增加引用计数,这自然必须少运行,因为生成的垃圾中只有一些(通常是很小的)部分包含循环.另一个因素是速度 - 一个聪明的,优化的GC可以比引用计数做得更好,特别是在存在线程的情况下(由于锁定,使得重新计算的递增/递减更加节省) (4认同)
  • @delnan不仅成本更高,Java线程使得引用计数几乎不可能.由于每个线程都可以自由地将对象的副本保存在自己的内存区域中,并在闲暇时将它们写回主区域,因此refcounts很快就会变得不一致. (3认同)

bes*_*sss 4

  1. 引用计数必须在对象外部完成。
  2. 计算参考文献的速度很慢。处理循环引用甚至更慢,但这并非不可能。还是很慢。
  3. 引用计数实际上非常慢,因为它必须使用 CAS + 循环
  4. 不计算引用更容易实现,而且速度更快,尤其是。使用一些操作系统内存页面技巧。
  5. 如果对象没有逃逸,则可以通过逃逸分析完全删除引用计数。