如何防止对象收集垃圾?
是否有通过终结或幻影引用的方法或任何其他方法?
采访中有人问我这个问题。面试官建议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