java基础之强引用
强引用介绍
强引用就是我们普遍使用一个对象时的方法,即类似Object obj=new Object()这种的引用方法。在强引用时,JVM即使内存溢出,抛出OutOfMemoryError错误,使程序运行中断,也不会去回收强引用对象解决内存溢出问题。因此在强引用对象用完时需要将强引用弱化,可将对象置为空obj=null

也就是说,我们平常进行操作的都是强引用对象。并且这部分对象都有指向内存中的一个地址,那么永远不会被回收。
demo演示
创建一个对象,并且重写Object中的finalize方法
public class M {
// 当GC在确定该对象不被引用后,就会调用这个方法,并且只会调用这个对象的这个方法,有且只有一次。
// 执行该方法后,该对象就会被丢弃
@Override
protected void finalize() {
System.out.println("finalize");
}
}
演示
public class Test {
public static void main(String[] args) throws IOException {
// 创建一个强引用对象
M m = new M();
// 若指向null,则会被垃圾回收器不定时回收
m = null;
// 主动调用gc回收对象
System.gc();
System.out.println(m);
// 阻塞主进程,可以更加清晰的查看调用finalize的过程
// 因为GC并不是使用主进程执行的,而是通过子进程执行,
// 如果不阻塞的话,就有可能看不到调用finalize,就会直接被结束
System.in.read();
}
}
finalize
FinalReference访问权限为package,并且只有一个子类Finalizer,同时Finalizer 是final修饰的类,所以无法继承扩展。
与Finalizer相关联的则是Object中的finalize()方法,在类加载的过程中,如果当前类有覆写finalize()方法,则其对象会被标记为finalizer类,这种类型的对象被回收前会先调用其finalize()。
具体的实现机制是,在gc进行可达性分析的时候,如果当前对象是finalizer类型的对象,并且本身不可达(与GC Roots无相连接的引用),则会被加入到一个ReferenceQueue类型的队列(F-Queue)中。而系统在初始化的过程中,会启动一个FinalizerThread实例的守护线程(线程名Finalizer),该线程会不断消费F-Queue中的对象,并执行其finalize()方法(runFinalizer),并且runFinalizer方法会捕获Throwable级别的异常,也就是说finalize()方法的异常不会导致FinalizerThread运行中断退出。对象在执行finalize()方法后,只是断开了与Finalizer的关联,并不意味着会立即被回收,还是要等待下一次GC,而每个对象的finalize()方法都只会执行一次,不会重复执行。
本文来自博客园,作者:King-DA,转载请注明原文链接:https://www.cnblogs.com/qingmuchuanqi48/articles/17464813.html

浙公网安备 33010602011771号