java - 垃圾回收器如何快速知道哪些对象不再有对它们的引用?

2022-09-01 21:13:52

我知道在Java中,如果一个对象不再有任何引用,垃圾回收器会在一段时间后将其回收。

但是,垃圾回收器如何知道对象具有或没有关联的引用呢?

垃圾回收器是否使用某种哈希映射或表?


编辑:

请注意,我不是在问gc通常是如何工作的。真的,我不是在问这个。

特别问的是,gc如何知道哪些对象是活的,哪些是死的,效率很高。

这就是为什么我在我的问题中说gc维护某种哈希映射或集合,并不断更新对象的引用数量?


答案 1

典型的现代 JVM 使用几种不同类型的垃圾回收器。

一种通常用于已经存在了一段时间的对象的类型称为“标记和扫描”。它基本上涉及从已知的“活动”对象(所谓的垃圾回收根)开始,遵循所有对象引用链,并将每个可访问的对象标记为“活动”。

完成此操作后,扫描阶段可以回收那些尚未标记为“活动”的对象。

要使此过程正常工作,JVM 必须知道每个对象引用在内存中的位置。这是垃圾回收器精确(Java就是这样)的必要条件。


答案 2

Java有各种不同的垃圾回收策略,但它们基本上都是通过跟踪哪些对象可以从已知的活动对象访问来工作的。

一个很好的总结可以在文章“垃圾回收在Java中的工作原理”中找到,但对于真正的低级,您应该查看使用5.0 Java[tm]虚拟机调整垃圾回收

当无法再从正在运行的程序中的任何指针访问某个对象时,该对象将被视为垃圾。最直接的垃圾回收算法只是循环访问每个可访问的对象。然后,任何遗留的物品都被视为垃圾。这种方法花费的时间与活动对象的数量成正比,这对于维护大量实时数据的大型应用程序来说是令人望而却步的。

从 J2SE 平台 1.2 版开始,虚拟机合并了许多不同的垃圾回收算法,这些算法使用分代收集进行组合。虽然朴素垃圾回收会检查堆中的每个活动对象,但代收集会利用大多数应用程序的几个经验观察到的属性来避免额外的工作。

这些观察到的最重要的特性是婴儿死亡率。...

也就是说,许多对象(如迭代器)只存在很短的时间,因此较年轻的对象比较旧的对象更有可能符合垃圾回收的条件。

有关更多最新的调优指南,请查看:

顺便说一句,要小心尝试猜测你的垃圾回收策略,我知道很多程序的性能被过度热心使用或不适当的选项所破坏。System.gc()-XX