WeakReference与SoftReference

WeakReference与SoftReference均可以用来保存对象的实例引用,这两个类与垃圾回收有关。java

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中。这样能够系统设计得更具弹性。测试

WeakReference的一个测试程序设计

import java.lang.ref.WeakReference;code

public class WeakReferenceTest {orm

/**
 * @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: 3get

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!");
}

}

程序运行结果:

Get str from object of SoftReference: Hello, reference, count: 1

Get str from object of SoftReference: Hello, reference, count: 2

Get str from object of SoftReference: Hello, reference, count: 3

Get str from object of SoftReference: Hello, reference, count: 4

Get str from object of SoftReference: Hello, reference, count: 5

Get str from object of SoftReference: Hello, reference, count: 6

Get str from object of SoftReference: Hello, reference, count: 7

Get str from object of SoftReference: Hello, reference, count: 8

Get str from object of SoftReference: Hello, reference, count: 9

Get str from object of SoftReference: Hello, reference, count: 10

System.gc() was invoked! Get str from object of SoftReference: Hello, reference, count: 11

Get str from object of SoftReference: Hello, reference, count: 12

Get str from object of SoftReference: Hello, reference, count: 13

Get str from object of SoftReference: Hello, reference, count: 14

Get str from object of SoftReference: Hello, reference, count: 15

Get str from object of SoftReference: Hello, reference, count: 16

Get str from object of SoftReference: Hello, reference, count: 17

Get str from object of SoftReference: Hello, reference, count: 18

Get str from object of SoftReference: Hello, reference, count: 19

Get str from object of SoftReference: Hello, reference, count: 20

System.gc() was invoked!

Get str from object of SoftReference: Hello, reference, count: 21

Get str from object of SoftReference: Hello, reference, count: 22

Get str from object of SoftReference: Hello, reference, count: 23

Get str from object of SoftReference: Hello, reference, count: 24

Get str from object of SoftReference: Hello, reference, count: 25

Get str from object of SoftReference: Hello, reference, count: 26

Get str from object of SoftReference: Hello, reference, count: 27

Get str from object of SoftReference: Hello, reference, count: 28

上面的打印结果会一直持续下去。 由于soft.get()一直不会为空 SoftReference比WeakReference生命力更强,当JVM的内存不吃紧时,即便引用的对象被置为空了,Soft还能够保留对该对象的引用,此时的JVM内存池实际上还保有原来对象,只有当内存吃紧的状况下JVM才会清除Soft的引用对象,而且会在将来从新加载该引用的对象。

而WeakReference则当清理内存池时会自动清理掉引用的对象。

相关文章
相关标签/搜索