当前位置: 首页 > 面试题库 >

如何防止对象收集垃圾?

宋宏儒
2023-03-14
问题内容

如何防止对象收集垃圾?

是否有通过终结或幻影引用的方法或任何其他方法?

采访中有人问我这个问题。面试官建议finalize()可以使用。


问题答案:

保持参考。如果过早地收集了对象,则表明您的应用程序设计中存在错误。

垃圾收集器仅收集应用程序中没有引用的对象。如果没有可以自然引用所收集对象的对象,请问自己为什么要保持它的生命。

通常没有引用但想要保留一个对象的一个​​用例是单例。在这种情况下,您可以使用静态变量。单例的一种可能实现如下所示:

public class Singleton {
  private static Singleton uniqueInstance;

  private Singleton() {
    }

  public static synchronized Singleton getInstance() {
    if (uniqueInstance == null) {
      uniqueInstance = new Singleton();
    }
    return uniqInstance;
  }
}

编辑:
从技术上讲,您可以将引用存储在终结器中的某个位置。这将防止对象被收集,直到收集器再次确定没有更多引用为止。但是,终结器最多只能调用一次,因此,您必须确保在第一个集合之后不需要终结您的对象(包括其超类)。但是,我建议您不要在实际程序中使用此技术。
(这会让像我这样的同事大喊WTF!?;)

  protected void finalize() throws Throwable {
    MyObjectStore.getInstance().store(this);
    super.finalize(); // questionable, but you should ensure calling it somewhere.
  }


 类似资料:
  • 有人能给我解释一下原因吗?

  • [GC(分配失败)[defnew:10931K->472K(12288K),0.0053905秒]10931K->10712K(39616K),0.0054285秒][times:user=0.00 sys=0.00,real=0.01秒] [GC(分配失败)[defnew:10712k->472k(12288k),0.0057686秒]20952k->20952k(39616k),0.00580

  • UPD 21.11.2017:该bug在JDK中被修复,参见Vicente Romero的评论 摘要: 如果语句用于任何实现,则集合将保留在堆内存中,直到当前作用域(方法、语句体)结束,即使您没有对集合的任何其他引用,并且应用程序需要分配新内存,也不会被垃圾收集。 在运行时,我有: 第一次内存分配前:最大176640K的1251K 第一次内存分配后:最大176640K的131426K 为了避免在函

  • 问题内容: 我有两节课 假设我在代码中使用对象B [say ],并在最终使用它后将其设置为。我知道B的对象现在可用于垃圾回收了。 我知道在将b设置为null之后,它将 立即有资格 进行垃圾回收吗?但是类型A的对象呢?将B设置为以后,是否可以 立即 将其用于垃圾回收?还是 在B被垃圾回收之后 才有资格 进行 垃圾回收 ? 从理论上讲,在对B进行垃圾收集之前,还有参考吗?因此,SUN JVM编译器将在

  • 每个java开发人员都知道,java对象不再使用时将被垃圾收集。我想知道JVM如何识别必须为垃圾收集选择的对象。(例如,如果我有10个对象。如果对10个对象中的2个进行垃圾收集,jvm将如何找到这两个对象)。 JVM使用标记和扫描算法(如果我是对的)。 1)例如我在下面提供字符串对象场景 //现在s1

  • 问题内容: UPD 21.11.2017: 该错误已在JDK中修复,请参见Vicente Romero的评论 摘要: 如果将语句用于任何实现,则集合将一直保留在堆内存中,直到当前作用域(方法,语句主体)结束为止,即使您没有对该集合和应用程序的任何其他引用,也不会进行垃圾回收需要分配一个新的内存。 http://bugs.java.com/bugdatabase/view_bug.do?bug_id