1.可能是是对象复活
2.finalize()执行的时间是不固定的,有GC决定,极端情况下,没有GC,就不会执行finalize()
3.一个糟糕的finalize()会影响GC的性能
对象复活
public class FinalizeActive{
public static FinalizeActive obj;
@Override
protected void finalize() throws Throwable {
System.out.println("执行finalize");
obj = this;
}
public static void main(String[] args) {
obj = new FinalizeActive();
//obj=null
obj = null;
System.gc();
System.out.println("After GC");
if(obj!=null)
System.out.println("对象复活");
obj = null;
System.out.println("After GC");
if(obj==null)
System.out.println("对象死亡");
}
}
一个糟糕的finalize()会影响GC的性能
finalize()由FinalizerThread线程执行,每一个被回收并且包含finalize()方法的对象都会加入FinalizerThread队列,该队列为一个引用
队列(ReferenceQueue),队列中的每一项为java.lang.ref.Finalizer对
象引用,本质是一个引用(强引用),意味着对象又变成可达的了,一旦性能出
现问题,这些垃圾对象将一直存在堆内存中占用资源
public class LongFinalize{
public static class LF{
private byte [] b = new byte[512];
@Override
protected void finalize() throws Throwable {
try {
System.out.println(Thread.currentThread().getId());
Thread.sleep(1000);
} catch (Exception e) {
//TODO: handle exception
e.printStackTrace();
}
}
}
public static void main(String[] args) {
long s = System.currentTimeMillis();
LF lf;
for(int i=0;i<100000;i++)
lf = new LF();
long e = System.currentTimeMillis();
System.out.println(e-s);
}
}
/**
* java -Xmx10m -Xms10m -XX:+PrintGCDetails
* -XX:+HeapDumpOutOfMemoryError
* -XX:HeapDumpPaht="H:/finalize.dump"
*
*/