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

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的一个测试程序:

Java代码

  1. import java.lang.ref.WeakReference;  
  2. public class WeakReferenceTest {  
  3. /**
  4.      * @param args
  5.      */
  6. public static void main(String[] args) {  
  7.         A a = new A();  
  8.         a.str = "Hello, reference";  
  9.         WeakReference<A> weak = new WeakReference<A>(a);  
  10.         a = null;  
  11. int i = 0;  
  12. while (weak.get() != null) {  
  13.             System.out.println(String.format("Get str from object of WeakReference: %s, count: %d", weak.get().str, ++i));  
  14. if (i % 10 == 0) {  
  15.                 System.gc();  
  16.                 System.out.println("System.gc() was invoked!");  
  17.             }  
  18. try {  
  19.                 Thread.sleep(500);  
  20.             } catch (InterruptedException e) {  
  21.             }  
  22.         }  
  23.         System.out.println("object a was cleared by JVM!");  
  24.     }  

Java代码 

  1. import java.lang.ref.WeakReference; 
  2. public class WeakReferenceTest { 
  3. /**
  4.      * @param args
  5.      */
  6. public static void main(String[] args) { 
  7.         A a = new A(); 
  8.         a.str = "Hello, reference"; 
  9.         WeakReference<A> weak = new WeakReference<A>(a); 
  10.         a = null; 
  11. int i = 0; 
  12. while (weak.get() != null) { 
  13.             System.out.println(String.format("Get str from object of WeakReference: %s, count: %d", weak.get().str, ++i)); 
  14. if (i % 10 == 0) { 
  15.                 System.gc(); 
  16.                 System.out.println("System.gc() was invoked!"); 
  17.             } 
  18. try { 
  19.                 Thread.sleep(500); 
  20.             } catch (InterruptedException e) { 
  21.             } 
  22.         } 
  23.         System.out.println("object a was cleared by JVM!"); 
  24.     } 

程序运行结果:

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

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

Java代码 

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

SoftReference的一个测试程序:

Java代码

  1. import java.lang.ref.SoftReference;  
  2. public class SoftReferenceTest {  
  3. /**
  4.      * @param args
  5.      */
  6. public static void main(String[] args) {  
  7.         A a = new A();  
  8.         a.str = "Hello, reference";  
  9.         SoftReference<A> sr = new SoftReference<A>(a);  
  10.         a = null;  
  11. int i = 0;  
  12. while (sr.get() != null) {  
  13.             System.out.println(String.format("Get str from object of SoftReference: %s, count: %d", sr.get().str, ++i));  
  14. if (i % 10 == 0) {  
  15.                 System.gc();  
  16.                 System.out.println("System.gc() was invoked!");  
  17.             }  
  18. try {  
  19.                 Thread.sleep(500);  
  20.             } catch (InterruptedException e) {  
  21.             }  
  22.         }  
  23.         System.out.println("object a was cleared by JVM!");  
  24.     }  

Java代码 

  1. import java.lang.ref.SoftReference; 
  2. public class SoftReferenceTest { 
  3. /**
  4.      * @param args
  5.      */
  6. public static void main(String[] args) { 
  7.         A a = new A(); 
  8.         a.str = "Hello, reference"; 
  9.         SoftReference<A> sr = new SoftReference<A>(a); 
  10.         a = null; 
  11. int i = 0; 
  12. while (sr.get() != null) { 
  13.             System.out.println(String.format("Get str from object of SoftReference: %s, count: %d", sr.get().str, ++i)); 
  14. if (i % 10 == 0) { 
  15.                 System.gc(); 
  16.                 System.out.println("System.gc() was invoked!"); 
  17.             } 
  18. try { 
  19.                 Thread.sleep(500); 
  20.             } catch (InterruptedException e) { 
  21.             } 
  22.         } 
  23.         System.out.println("object a was cleared by JVM!"); 
  24.     } 

程序运行结果:

Java代码

  1. Get str from object of SoftReference: Hello, reference, count: 1
  2. Get str from object of SoftReference: Hello, reference, count: 2
  3. Get str from object of SoftReference: Hello, reference, count: 3
  4. Get str from object of SoftReference: Hello, reference, count: 4
  5. Get str from object of SoftReference: Hello, reference, count: 5
  6. Get str from object of SoftReference: Hello, reference, count: 6
  7. Get str from object of SoftReference: Hello, reference, count: 7
  8. Get str from object of SoftReference: Hello, reference, count: 8
  9. Get str from object of SoftReference: Hello, reference, count: 9
  10. Get str from object of SoftReference: Hello, reference, count: 10
  11. System.gc() was invoked!  
  12. Get str from object of SoftReference: Hello, reference, count: 11
  13. Get str from object of SoftReference: Hello, reference, count: 12
  14. Get str from object of SoftReference: Hello, reference, count: 13
  15. Get str from object of SoftReference: Hello, reference, count: 14
  16. Get str from object of SoftReference: Hello, reference, count: 15
  17. Get str from object of SoftReference: Hello, reference, count: 16
  18. Get str from object of SoftReference: Hello, reference, count: 17
  19. Get str from object of SoftReference: Hello, reference, count: 18
  20. Get str from object of SoftReference: Hello, reference, count: 19
  21. Get str from object of SoftReference: Hello, reference, count: 20
  22. System.gc() was invoked!  
  23. Get str from object of SoftReference: Hello, reference, count: 21
  24. Get str from object of SoftReference: Hello, reference, count: 22
  25. Get str from object of SoftReference: Hello, reference, count: 23
  26. Get str from object of SoftReference: Hello, reference, count: 24
  27. Get str from object of SoftReference: Hello, reference, count: 25
  28. Get str from object of SoftReference: Hello, reference, count: 26
  29. Get str from object of SoftReference: Hello, reference, count: 27
  30. Get str from object of SoftReference: Hello, reference, count: 28

自己的标注 写道

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

WeakReference与SoftReference的更多相关文章

  1. Java中的 WeakReference 和 SoftReference

    我们知道Java语言中没有指针,取而代之的是引用reference.Java中的引用又可以分为四种:强引用,弱引用(WeakReference),软引用(SoftReference),虚引用(Phan ...

  2. WeakReference 与 SoftReference 区别

    装载自:http://flyneil.iteye.com/blog/1345177 WeakReference与SoftReference都可以用来保存对象的实例引用,这两个类与垃圾回收有关. Wea ...

  3. Java 中 WeakReference 与 SoftReference 的区别?

    虽然 WeakReference 与 SoftReference 都有利于提高 GC 和 内存的效率, 但是 WeakReference ,一旦失去最后一个强引用,就会被 GC 回收,而软引用 虽然不 ...

  4. 【转】Java之WeakReference与SoftReference使用讲解

    Java 2 平台引入了 java.lang.ref 包,其中包括的类可以让您引用对象,而不将它们留在内存中.这些类还提供了与垃圾收集器(garbage collector)之间有限的交互. 1.先“ ...

  5. java基础回顾(六)——WeakReference、SoftReference

    在Java里, 当一个对象o被创建时, 它被放在Heap里. 当GC运行的时候, 如果发现没有任何引用指向o, o就会被回收以腾出内存空间. 或者换句话说, 一个对象被回收, 必须满足两个条件: 1) ...

  6. Java的引用StrongReference、 SoftReference、 WeakReference 、PhantomReference

    1. Strong Reference StrongReference 是 Java 的默认引用实现,  它会尽可能长时间的存活于 JVM 内, 当没有任何对象指向它时 GC 执行后将会被回收 @Te ...

  7. Android内存管理(3)缓存不要用SoftReference, 用android.util.LruCache

    A reference that is cleared when its referent is not strongly reachable and there is memory pressure ...

  8. Android性能优化之巧用软引用与弱引用优化内存使用

    前言: 从事Android开发的同学都知道移动设备的内存使用是非常敏感的话题,今天我们来看下如何使用软引用与弱引用来优化内存使用.下面来理解几个概念. 1.StrongReference(强引用) 强 ...

  9. Java泛型

    什么是泛型? 泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数化类型时指定的类型的一个 ...

随机推荐

  1. jquery插件的几种写法

    /** * Created by peng on 2016/12/8. */jQuery.extend({ min: function(a, b) { return a < b ? a : b; ...

  2. Java-Runoob-高级教程-实例-方法:15. Java 实例 – 重载(overloading)方法中使用 Varargs

    ylbtech-Java-Runoob-高级教程-实例-方法:15. Java 实例 – 重载(overloading)方法中使用 Varargs 1.返回顶部 1. Java 实例 - 重载(ove ...

  3. git安装及git命令的用法

    git安装流程 https://git-scm.com/download/win (官网下载) git安装步骤 1.双击安装包 图文解释:

  4. [UE4]客户端-服务器模式

    客户端负责表现.服务器端负责数据. 以掉血为例: 一.玩家A砍了B一刀 二.服务器计算伤害,修改B的血量 三.把B的血量发给B,A砍B的动作发给所有能看到的玩家 四.客户端播放掉血量(如果允许可见), ...

  5. SCCM2012 R2实战系列之九:OSD(中)--捕获镜像

    在上篇文章中我们详细的完成了OSD的初始化配置.导入镜像.任务序列的创建和常见问题的排错.但是在实际环境中这样分发了干净的操作系统后还需要手动为客户端安装各种各样的应用程序.所以更为好的方法是将一台计 ...

  6. 第9章 应用层(6)_SMTP和POP3/IMAP协议

    7. 电子邮件 7.1 电子邮件发送和接收过程 (1)图解电子邮件的发送 ①一个电子邮件系统应具备三个主要组成构件:A用户代理(如Outlook).B邮件服务器.C邮件发送和接收协议(分别为SMTP和 ...

  7. virtual box + win7 + usb + share folder

    1.enable virtaulization on BIOS 2.new machine setup, memory, harddisk size 3. 4.install extension pa ...

  8. 7 家 IT 厂商 6394.5 万元中标天津公安云项目(虚拟化、数据库、软件开发)

    http://mp.weixin.qq.com/s/kjum54HJorGTPtZiM-HE1g 天津市公安局云计算平台项目分为:大数据部分.虚拟化部分.数据库部分,软件开发部分,预算分别为:2350 ...

  9. SQL Server 2016:内存列存储索引

    作者 Jonathan Allen,译者 谢丽 SQL Server 2016的一项新特性是可以在“内存优化表(Memory Optimized Table)”上添加“列存储索引(Columnstor ...

  10. WPF 自定义分页控件一

    一:右键添加新建项,选择新建自定义控件,命名为:KDataPager public class KDataPager : Control { static KDataPager() { Default ...