jvm reference

JDK1.2之后,把对象的引用分为四种状态,即强引用、软引用、弱引用和虚引用。这样的方式,可以更加灵活地控制对象的生命周期。
 
一、强引用
开发中用的最多的就是强引用了。

强引用声明格式:

String str="abc";
只要某个对象与强引用关联,那么JVM在内存不足的情况下,宁愿抛出outOfMemoryError错误,也不会回收此类对象。

【1】如果我们想要JVM回收此类被强引用关联的对象,我们可以显示地将str置为null,那么JVM就会在合适的时间回收此对象。

二、软引用
java中使用SoftRefence来表示软引用,如果某个对象与软引用关联,那么JVM只会在内存不足的情况下回收该对象。

那么利用这个特性,软引用可以用来做缓存。

软引用声明格式:

import java.lang.ref.SoftReference;
 
public class TestRef {
    public static void main(String args[]) {
        SoftReference<String> str = new SoftReference<String>(new String("abc"));
        System.out.println(str.get());
        //通知JVM进行内存回收
        System.gc();
        System.out.println(str.get());
    }
}
输出:

可以看得出来,此时JVM内存充足,暂时还没有回收被软引用关联的对象。

【1】软引用适合做缓存,在内存足够时,直接通过软引用取值,无需从真实来源中查询数据,可以显著地提升网站性能。当内存不足时,能让JVM进行内存回收,从而删除缓存,这时候只能从真实来源查询数据。

三、弱引用
 

java中使用WeakReference来表示弱引用。如果某个对象与弱引用关联,那么当JVM在进行垃圾回收时,无论内存是否充足,都会回收此类对象。

弱引用声明格式:

import java.lang.ref.WeakReference;
 
public class TestRef {
    public static void main(String args[]) {
        WeakReference<String> str = new WeakReference<String>(new String("abc"));
        System.out.println(str.get());
        //通知JVM进行内存回收
        System.gc();
        System.out.println(str.get());
    }
}
输出:

可以看得出来,被弱引用关联的对象,总是会在垃圾回收时被回收掉。

注意:(1)System.out.println(str.get());有可能取不到str的值。这是因为我们在声明了弱引用之后,立即对其输出,而gc线程是一个优先级很低的守护线程,还来不及扫描该该对象所在的区域,即来不及对该对象的回收。如果我们在声明之后的很长时间后,再次get,是有可能get不到值的。

【1】弱引用可以在回调函数在防止内存泄露。因为回调函数往往是匿名内部类,一个非静态的内部类会隐式地持有外部类的一个强引用,当JVM在回收外部类的时候,此时回调函数在某个线程里面被回调的时候,JVM就无法回收外部类,造成内存泄漏。在安卓activity内声明一个非静态的内部类时,如果考虑防止内存泄露的话,应当显示地声明此内部类持有外部类的一个弱引用。

四、虚引用
java中使用PhantomReference来表示虚引用。虚引用,虚引用,引用就像形同虚设一样,就像某个对象没有引用与之关联一样。若某个对象与虚引用关联,那么在任何时候都可能被JVM回收掉。虚引用不能单独使用,必须配合引用队列一起使用。

虚引用声明格式:

import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
 
 
public class TestRef {
    public static void main(String args[]) {
        ReferenceQueue<String> queue = new ReferenceQueue<>();
        PhantomReference<String> str = new PhantomReference<String>("abc", queue);
        System.out.println(str.get());
 
    }
}
输出:

可见使用get方法无法获取该对象的值

【1】当垃圾回收器准备回收一个对象时,如果发现它与虚引用关联,就会在回收它之前,将这个虚引用加入到引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被回收,如果确实要被回收,就可以做一些回收之前的收尾工作。
 

原文:https://blog.csdn.net/qq_41723615/category_9704605.html

发布了740 篇原创文章 · 获赞 65 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_41723615/article/details/104342675
JVM
今日推荐