WeakReference与SoftReference

简介:

SoftReference(软引用)、WeakReference(弱引用),这两个类是对heap中java对象的应用,通过这个两个类可以和gc做简单的交互。

 

WeakReference是弱引用,其中保存的对象实例可以被GC回收掉。这个类通常用于在某处保存对象引用,而又不干扰该对象被GC回收,通常用于Debug、内存监视工具等程序中。因为这类程序一般要求即要观察到对象,又不能影响该对象正常的GC过程。

最近在JDK的Proxy类的实现代码中也发现了Weakrefrence的应用,Proxy会把动态生成的Class实例暂存于一个由Weakrefrence构成的Map中作为Cache。

 

SoftReference是强引用,它保存的对象实例,除非JVM即将OutOfMemory,否则不会被GC回收。这个特性使得它特别适合设计对象Cache。对于Cache,我们希望被缓存的对象最好始终常驻内存,但是如果JVM内存吃紧,为了不发生OutOfMemoryError导致系统崩溃,必要的时候也允许JVM回收Cache的内存,待后续合适的时机再把数据重新Load到Cache中。这样可以系统设计得更具弹性。

强引用                                                                                

Object o=new Object();    
Object o1=o;

上面代码中第一句是在heap堆中创建新的Object对象通过o引用这个对象,第二句是通过o建立o1到new Object()这个heap堆中的对象的引用,这两个引用都是强引用.只要存在对heap中对象的引用,gc就不会收集该对象.如果通过如下代码:

o=null;    
o1=null;

如果显式地设置o和o1为null,或超出范围,则gc认为该对象不存在引用,这时就可以收集它了。可以收集并不等于就一会被收集,什么时候收集这要取决于gc的算法,这要就带来很多不确定性。例如你就想指定一个对象,希望下次gc运行时把它收集了,那就没办法了,有了其他的两种引用就可以做到了。其他两种引用在不妨碍gc收集的情况下,可以做简单的交互。

heap中对象有强可及对象、软可及对象、弱可及对象、虚可及对象和不可到达对象。应用的强弱顺序是强、软、弱、和虚。对于对象是属于哪种可及的对象,由他的最强的引用决定。如下:

 

WeakReference                                                                      

复制代码
import java.lang.ref.WeakReference;   
  
public class WeakReferenceTest {   
  
    /**  
     * @param args  
     */  
    public static void main(String[] args) {   
        A a = new A();   
        a.str = "Hello, reference";   
        WeakReference<A> weak = new WeakReference<A>(a);   
        a = null;   
        int i = 0;   
        while (weak.get() != null) {   
            System.out.println(String.format("Get str from object of WeakReference: %s, count: %d", weak.get().str, ++i));   
            if (i % 10 == 0) {   
                System.gc();   
                System.out.println("System.gc() was invoked!");   
            }   
            try {   
                Thread.sleep(500);   
            } catch (InterruptedException e) {   
  
            }   
        }   
        System.out.println("object a was cleared by JVM!");   
    }   
  
}
复制代码

程序运行结果:

复制代码
Get str from object of WeakReference: Hello, reference, count: 1  
Get str from object of WeakReference: Hello, reference, count: 2  
Get str from object of WeakReference: Hello, reference, count: 3  
Get str from object of WeakReference: Hello, reference, count: 4  
Get str from object of WeakReference: Hello, reference, count: 5  
Get str from object of WeakReference: Hello, reference, count: 6  
Get str from object of WeakReference: Hello, reference, count: 7  
Get str from object of WeakReference: Hello, reference, count: 8  
Get str from object of WeakReference: Hello, reference, count: 9  
Get str from object of WeakReference: Hello, reference, count: 10  
System.gc() was invoked!   
object a was cleared by JVM!
复制代码

SoftReference                                                                        

复制代码
import java.lang.ref.SoftReference;   
  
public class SoftReferenceTest {   
  
    /**  
     * @param args  
     */  
    public static void main(String[] args) {   
        A a = new A();   
        a.str = "Hello, reference";   
        SoftReference<A> sr = new SoftReference<A>(a);   
        a = null;   
        int i = 0;   
        while (sr.get() != null) {   
            System.out.println(String.format("Get str from object of SoftReference: %s, count: %d", sr.get().str, ++i));   
            if (i % 10 == 0) {   
                System.gc();   
                System.out.println("System.gc() was invoked!");   
            }   
            try {   
                Thread.sleep(500);   
            } catch (InterruptedException e) {   
  
            }   
        }   
        System.out.println("object a was cleared by JVM!");   
    }   
  
}
复制代码

总结                                                                                   

SoftReference比WeakReference生命力更强,当JVM的内存不吃紧时,即使引用的对象被置为空了,Soft还可以保留对该对象的引用,此时的JVM内存池实际上还保有原来对象,只有当内存吃紧的情况下JVM才会清除Soft的引用对象,并且会在未来重新加载该引用的对象。
而WeakReference则当清理内存池时会自动清理掉引用的对象。

我是天王盖地虎的分割线                                                             

 

 




本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/3955055.html,如需转载请自行联系原作者

相关文章
|
1月前
|
存储 Java 程序员
深入理解ThreadLocal及其弱引用
深入理解ThreadLocal及其弱引用
|
4月前
|
存储 缓存 Java
|
缓存 Java 程序员
Java 中的强引用、弱引用、软引用和虚引用
引用方式内存不足时垃圾回收机制启动时其余情况强引用否否否软引用是否否弱引用是是否虚引用可能可能可能在一般的程序中,弱引用和虚引用很少会被用到,强引用天天都在用就不必我说了,在有些情况下(如资源文件很大,但并不是全部要在同一时刻使用)我们会使用软引用来代替原来的强引用,一是可以避免某些情况下产生的 OOM,此外,它可以减少程序使用的内存,加速程序的运行。
105 1
|
7月前
|
Java
【JVM】深入理解Java引用类型:强引用、软引用、弱引用和虚引用
【JVM】深入理解Java引用类型:强引用、软引用、弱引用和虚引用
528 0
|
算法 Java C++
14-理解Java中的不同引用类型:强引用、软引用、弱引用和虚引用
这篇文章将深入探讨Java中的四种引用类型:强引用、软引用、弱引用和虚引用。我们将逐一解释每种引用类型的特性和用途。
121 0
14-理解Java中的不同引用类型:强引用、软引用、弱引用和虚引用
|
存储 缓存 Java
Java的WeakHashMap:理解弱引用与垃圾回收
本文将介绍WeakHashMap的原理和用途,并结合代码示例演示如何在Java中利用WeakHashMap实现自动资源管理和缓存清理。
|
Java
强引用、软引用、弱引用、虚引用的区别?
强引用、软引用、弱引用、虚引用的区别?
87 0
|
Java C++
Java引用类型:强引用,软引用,弱引用,虚引用
Java引用类型:强引用,软引用,弱引用,虚引用
89 0
|
算法 Java
java中的强引用、软引用、弱引用、虚引用
java中将引用类型分为强引用、软引用、弱引用、虚引用。之所以要这么划分,还是为了GC时更好的对对象进行处理。因为jvm已经明确了各种引用的GC方式,所以谈四种引用最好是和GC一起聊才会有意义(个人愚见)。
150 0
|
缓存 Java API
Java的强引用、软引用、弱引用、虚引用
Java的强引用、软引用、弱引用、虚引用
Java的强引用、软引用、弱引用、虚引用