finalize()
finalize()是Object中的方法,当垃圾回收器将要回收对象所占内存之前被调用,即当一个对象被虚拟机宣告死亡时会先调用它finalize()方法。
我们先重写一下finalize方法加一个输出方便查看Jvm何时回收引用
public class M {
//重写此方法主要用来观察是否进行了回收
@Override
protected void finalize() throws Throwable {
System.out.println("回收");
super.finalize();
}
}
强引用
某一个变量直接指向new出来的某一块内存区域,我们把它称之为强引用。当内存区域没有被任何变量指向的时候Jvm回直接回收掉这块区域。我们来看案例
public class strongReference {
public static void main(String[] args) throws IOException {
//强引用
M m=new M();
m=null;
System.gc();
System.in.read();//阻塞线程看效果
}
}
运行以上main方法,输出结果如下,可以看到我们重写的finalize()方法被调用了,证明一旦没有变量指向的强引用内存区域Jvm会直接回收掉。
软引用
软引用是使用SoftReference创建的引用,被引用的对象在内存不足的时候才会被Jvm回收。
public class softReference {
public static void main(String[] args) {
String s=new String("小熊");//强引用
SoftReference<String> softReference=new SoftReference<>(s);//软引用 指向了new String("小熊");
s = null;//s指向null
System.out.println(softReference.get());
}
}
这里变量s持有对字符串对象的强引用,而softReference持有了该对象的软引用,虽然执行了s = null强引用关联取消,但是还剩softReference软引用new String("小熊")这块内存区域不会被回收,但是在内存不足发生Full GC这个字符串对象会被回收。
弱引用
只要遭遇到GC就会被回收
public class weakReference {
public static void main(String[] args) {
WeakReference<M> weakReference=new WeakReference<>(new M());//弱引用指向m
System.out.println(weakReference.get());
System.gc();
System.out.println(weakReference.get());
}
}
虚引用
虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。和弱引用很相似,那么它和弱引用的区别又是什么呢?虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。你声明虚引用的时候是要传入一个queue的。当你的虚引用所引用的对象已经执行完finalize函数的时候,就会把对象加到queue里面。你可以通过判断queue里面是不是有对象来判断你的对象是不是要被回收了。
评论区