跳到正文
堆栈茶社
返回

Java中的强引用、软引用、弱引用、虚引用

更新于:
—次阅读
编辑此页

Java 对象的引用划分为4种,它们由强到弱依次是强引用、软引用、弱引用、虚引用。这样划分的作用是可以更好的控制对象的声明周期,有利于JVM 进行垃圾回收。

强引用(StrongReference)

强引用就是我们最常见的普通对象引用,通常我们通过new来创建的对象所产生的引用就是强引用,强引用的对象不可被JVM垃圾收集器回收。

比如下面这段代码,obj和str都是强引用。

Object obj = new Object();
String str = "liuqitech";

只要某个对象有强引用与之关联,JVM必定不会回收这个对象,即使在内存不足的情况下,JVM宁愿抛出OOM的错误也不会回收这种对象。比如下面的代码中

public class Main {
    public static void main(String[] args) {
        new Main().fun1();
    }
     
    public void fun1() {
        Object object = new Object();
        Object[] objArr = new Object[1000];
    }
}

当运行至Object[] objArr = new Object[1000];时,即使内存不足抛出OOM错误,也不会回收object所引用的对象。不过要注意的是当fun1()方法执行完毕后,object、objArr都已经不存在,所以他们指向的对象会被JVM回收。

如果想中队强引用和某个对象之间的关联,可以显示的将引用赋值为null(如object = null),这样JVM就会在合适的时机回收原object所指向的对象。

软引用(SoftReference)

软引用是一种相对强引用弱化一些的引用,可以让对象豁免一些垃圾收集,只有当 JVM 认为内存不足时,才会去试图回收软引用指向的对象。JVM 会确保在抛出 OutOfMemoryError 之前,清理软引用指向的对象。软引用通常用来实现内存敏感的缓存,如果还有空闲内存,就可以暂时保留缓存,当内存不足时清理掉,这样就保证了使用缓存的同时,不会耗尽内存。

SoftReference<String> sr = new SoftReference<String>(new String("hello"));
System.out.println(sr.get());

软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被回收,则这个软引用进入到与之关联的引用队列中。

弱引用(WeakReference)

弱引用并不能使对象豁免垃圾收集,仅仅是提供一种访问在弱引用状态下对象的途径。这就可以用来构建一种没有特定约束的关系,比如,维护一种非强制性的映射关系,如果试图获取时对象还在,就使用它,否则重现实例化。它同样是很多缓存实现的选择。

public class Main {
    public static void main(String[] args) {
     
        WeakReference<String> sr = new WeakReference<String>(new String("hello"));
         
        System.out.println(sr.get()); // hello
        System.gc();                //通知JVM的gc进行垃圾回收
        System.out.println(sr.get()); // null
    }
}

同样弱引用也可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被回收,则将这个若引用进入到与之关联的引用队列中。

虚引用(PhantomReference)

虚引用也被翻译为幻象引用,你不能通过它访问对象。幻象引用仅仅是提供了一种确保对象被 finalize 以后,做某些事情的机制。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。

虚引用必须和引用队列联合使用。

public class Main {
    public static void main(String[] args) {
        ReferenceQueue<String> queue = new ReferenceQueue<String>();
        PhantomReference<String> pr = new PhantomReference<String>(new String("hello"), queue);
        System.out.println(pr.get()); // null
    }
}
待补充
参考文档

https://www.cnblogs.com/dolphin0520/p/3784171.html


编辑此页
分享这篇文章:

上一篇
Spring学习笔记 - Spring AOP 使用
下一篇
中兴 E8820 V2 资料