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则当清理内存池时会自动清理掉引用的对象。