WeakReference与SoftReference均可以用来保存对象的实例引用,这两个类与垃圾回收有关。
javascript
WeakReference是弱引用,其中保存的对象实例能够被GC回收掉。这个类一般用于在某处保存对象引用,而又不干扰该对象被GC回收,一般用于Debug、内存监视工具等程序中。由于这类程序通常要求即要观察到对象,又不能影响该对象正常的GC过程。java
最近在JDK的Proxy类的实现代码中也发现了Weakrefrence的应用,Proxy会把动态生成的Class实例暂存于一个由Weakrefrence构成的Map中做为Cache。缓存
SoftReference是强引用,它保存的对象实例,除非JVM即将OutOfMemory,不然不会被GC回收。这个特性使得它特别适合设计对象Cache。对于Cache,咱们但愿被缓存的对象最好始终常驻内存,可是若是JVM内存吃紧,为了避免发生OutOfMemoryError致使系统崩溃,必要的时候也容许JVM回收Cache的内存,待后续合适的时机再把数据从新Load到Cache中。这样能够系统设计得更具弹性。app
WeakReference的一个测试程序:ide
- 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!");
- }
-
- }
- 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!
- 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!");
- }
-
- }
- 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!");
- }
-
- }
程序运行结果:idea
- 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则当清理内存池时会自动清理掉引用的对象。