java – 垃圾收集器如何快速知道哪些对象不再引用它们?

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

但是垃圾收集器如何知道某个对象是否有与之关联的引用?

垃圾收集器是使用某种hashmap还是表?


编辑:

请注意,我不是在问gc的工作原理。 真的,我不是那么想的。

特别要求gc知道哪些对象是活的,哪些是死的,效率很高。

这就是为什么我在我的问题中说gc维护某种hashmap或set,并且不断更新对象的引用数量?

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

经常用于已经存在一段时间的物体的一种类型称为Mark-and-Sweep 。 它基本上涉及从已知的“实时”对象(所谓的垃圾收集根 )开始,遵循所有对象引用链,并将每个可到达对象标记为“活动”。

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

要使此过程起作用,JVM必须知道每个对象引用的内存位置。 这是垃圾收集器精确的必要条件(Java是什么)。

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

一个很好的总结可以在文章垃圾收集如何在Java中工作,但对于真正的低调,你应该看看使用5.0 Java [tm]虚拟机调优垃圾收集

当一个对象无法再从正在运行的程序中的任何指针到达时,它被认为是垃圾。 最直接的垃圾收集算法简单地遍历每个可到达的对象。 剩下的任何对象都被认为是垃圾。 这种方法所花费的时间与活动对象的数量成正比,这对于维护大量实时数据的大型应用程序来说是不可行的。

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

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

即迭代器之类的许多对象只能在很短的时间内存活,因此较年轻的对象比旧的对象更有可能有资格进行垃圾收集。

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

  • Java SE 6 HotSpot [tm]虚拟机垃圾收集调整
  • Java平台标准版HotSpot虚拟机垃圾收集调优指南 (Java SE 8)

顺便说一下,小心尝试再次猜测你的垃圾收集策略,我已经知道很多程序性能会因过度使用System.gc()或不适当的-XX选项而被破坏。

GC将知道可以尽快删除对象。 您不应该管理此过程。

但你可以非常礼貌地要求GC使用System.gc()运行。 这只是系统的一个提示。 GC不必在那一刻运行,它不必删除您的特定对象等。因为GC是BIG老板而我们(Java程序员)只是它的奴隶…… 🙁