如何通过GC(垃圾回收器)标记垃圾回收对象?

2022-09-04 01:01:04

在 Java 中,有没有办法在 GC 的下一个清理周期中将对象标记为垃圾回收?

我听说将对象设置为不再有效。null


答案 1

不能。如果另一个变量引用了它,你会期望发生什么?

请注意,不能将对象设置为 null - 只能将变量设置为 null。如果另一个变量仍然具有对该对象的引用,则它仍然不符合垃圾回收的条件。

如果你认为你需要这样做,这可能意味着你误解了你的数据 - 或者你可能在代码中的某个地方有泄漏(例如,你只向其中添加条目的列表,由静态变量引用 - 当类加载器处于活动状态时,这些条目将永远不符合垃圾回收的条件)。

每个JVM都有自己的GC,但在Hotspot中,下次GC运行该对象当前“居住”的一代时,对象将被垃圾回收(假设它没有终结器,这使事情复杂化)。如果物体是“年轻”的一代,这可能很快就会发生 - 如果它是在“老”一代,它可能需要更长的时间。

您可能希望查看Java 6 GC调优文档以获取更多信息,尽管当然从那时起,OpenJDK 7等已经发生了变化。


答案 2

我知道这个问题已经得到了回答,但是有一些方法可以操纵Java垃圾回收器查看您的引用的方式。您可以通过软引用、弱引用和幻像引用来执行此操作。看看java.lang.ref包,以获得更好的解释。

此外,下面是一个很好的示例,用于确定何时将对 PhantomReference 进行垃圾回收:

幻像引用用于确定对象何时即将被回收。使用幻像引用比终结更安全,因为一旦对象是幻像可访问的,它就不能复活。

// Create the phantom reference.
ReferenceQueue rq = new ReferenceQueue();
PhantomReference pr = new PhantomReference(object, rq);

// Wait until the object is about to be reclaimed.
try {
    while (true) {
        Reference r = rq.remove();
        if (r == pr) {
            // The object is about to be reclaimed.
            // Clear the referent so that it can be reclaimed.
            r.clear();
        }
    }
} catch (InterruptedException e) {
}