将非静态变量更改为静态变量

Change a Non Static Variable to Static Variable

我正在阅读有关 GC 的内容,并了解到当一个对象符合垃圾回收条件时,GC 必须 运行 对它使用 finalize 方法。 finalize 方法只保证 运行 一次,因此 GC 将对象标记为已完成并让它休息直到下一个周期。

在finalize方法中,你可以在技术上“复活”一个对象,例如,通过将它分配给一个静态字段。该对象将再次变为活动状态并且不符合垃圾回收条件,因此 GC 将不会在下一个循环中收集它。

但是,该对象将被标记为已完成,因此当它再次符合条件时,不会调用 finalize 方法。从本质上讲,您只能在对象的生命周期内使用一次这种“复活”技巧。

我觉得这很有趣。但是,如果我的变量是非静态变量,如何在 finalize 方法中将其更改为静态变量?

记住:

如果无法从任何活动线程或任何静态引用访问对象,则该对象有资格进行垃圾收集或 GC。所以 hack 是将对象添加到 finalize 方法内的静态资源,这只会阻止垃圾收集一次。 finalize 方法是受保护的,因此可以被子类覆盖,无论它们是否在同一个包中。

这是一种危险的做法,不需要在应用程序代码中使用。

在运行时更改变量定义并不容易,在某些情况下几乎是不可能的。可能有一些讨厌的反射技巧,可能涉及内联编译、类加载等,但你不应该那样做。将变量从静态更改为非静态或反之亦然还涉及在存储中移动数据并处理潜在的冲突 - 所以不要那样做。

无论如何,变量只是引用,要恢复一个对象,您只需要从实时线程创建一个新引用。这可以通过静态变量引用的一些集合来完成,并且 this 引用被添加到其中。

示例(仅供参考,不要使用它,除非您真的知道自己在做什么并且有充分的理由):

class NastyResurrector {
  public static Collection<Object> RESURRECTED_OBJECTS = ...;// use whatever collection implementation you like
}

然后在 finalize() 你会调用 NastyResurrector.RESURRECTED_OBJECTS.add(this) 然后你有你的参考。

但是,我将引用 source of your question(问题 Q11)中的内容:

Beware that this ugly hack should be used only if you really know what you’re doing

这是我认为最重要的收获。