`
wiseideal
  • 浏览: 448976 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

WeakReference与SoftReference

    博客分类:
  • java
 
阅读更多

装载自:http://flyneil.iteye.com/blog/1345177

 

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

}

 程序运行结果:

 

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

 

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

}

 程序运行结果:

 

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

 

 

分享到:
评论
3 楼 supertangcugu 2017-06-30  
文中有个错误,SoftReference是软引用,StrongReference才是强引用
2 楼 lydawen 2015-03-03  
自治州 写道
jvm是如何判断即将OutOfMemory的呢? 这个判断标准是否能够配置呢? 比如说, jvm判断当可分配的内存少于5M时为OutOfMemory, 那么这个5M能否被配置为10M或者其他任意数字呢?


-XX:CMSInitiatingOccupancyFraction=70
表示old区用到70%就开始回收,这个是默认的,你可以根据情况调整它。例如99%才回收,当然这个可能会比较危险,会造成真的OOM。
1 楼 自治州 2014-01-23  
jvm是如何判断即将OutOfMemory的呢? 这个判断标准是否能够配置呢? 比如说, jvm判断当可分配的内存少于5M时为OutOfMemory, 那么这个5M能否被配置为10M或者其他任意数字呢?

相关推荐

    SoftReference、WeakReference和PhantomRefrence分析和比较

    SoftReference、WeakReference和PhantomReference分析和比较 在 Java 中,引用类型分为强引用、软引用、弱引用和虚引用四种。强引用是我们最常用的引用类型,而软引用、弱引用和虚引用则是 Java 为我们提供的三种...

    JVM 77 道面试题及答案.docx

    4. WeakReference 与 SoftReference: WeakReference 和 SoftReference 都可以用于提高 GC 和内存的效率,但是 WeakReference 一旦失去最后一个强引用,就会被 GC 回收,而软引用虽然不能阻止被回收,但是可以延迟到...

    安卓Android源码——图片下载以及内存处理防OOM.zip

    3. **WeakReference与SoftReference**:使用WeakReference或SoftReference持有Bitmap或其他大型对象,当内存不足时,这些引用的对象会优先被回收。 4. **Memory Analyzer Tool (MAT)**:Android提供的内存分析工具...

    Android-memroy.zip_android_android 优化

    3. **WeakReference与SoftReference** 使用WeakReference和SoftReference可以帮助开发者实现弱引用和软引用,让对象在内存不足时能被及时回收,防止内存泄漏。 4. **Bitmap优化** Bitmap是Android中消耗内存的...

    Android应用源码之防止内存溢出浅析.zip

    8. **WeakReference与SoftReference**:使用WeakReference或SoftReference可以弱化对象引用,让垃圾收集器更容易回收。 9. **内存分析工具**:Android Studio提供了内存分析工具,通过实时监控内存分配和使用,找出...

    JVM 77道面试题和答案.docx

    4. **WeakReference与SoftReference**:两者都与内存管理和GC有关。WeakReference的对象一旦没有强引用,就会立即被GC回收。SoftReference则稍微“软”一些,只有在系统内存不足时才会被回收。 5. **-XX:+...

    Java集合面试,共52道题目

    12. WeakReference与SoftReference: - 弱引用和软引用用于内存管理,当垃圾收集器需要内存时,会清除这些引用的对象。 13. Java 8的流(Stream)和Lambda表达式: - 流提供了新的集合处理方式,可以方便地进行过滤...

    java复习文档,含.md程序

    6. **WeakReference与SoftReference**:弱引用和软引用在内存管理中起着重要作用,它们不会阻止垃圾回收,但软引用在内存不足时才会被回收。 7. **Map接口**:除了HashMap和TreeMap,还有LinkedHashMap,它保持插入...

    Java程序员反馈的百度的笔试题.docx

    16. **WeakReference与SoftReference**: WeakReference对象会在垃圾收集时立即被清除,即使存在引用。SoftReference则在内存不足时才会被回收,用于缓存策略。 17. **HashSet内部工作原理**: HashSet基于...

    StrongReference,SoftReference, WeakReference的使用实例

    StrongReference,SoftReference, WeakReference的使用实例,请参照博客:http://blog.csdn.net/To_be_Designer/article/details/72673421

    Java基础面试题以及几个很有用的刷题网站.docx

    #### 十八、WeakReference与SoftReference的区别 - **软引用**:当内存空间足够时,软引用可以长时间存在,只有在内存不足时才会被回收。 - **弱引用**:只要发生垃圾回收,不管内存是否足够,弱引用都会被回收。弱...

    00M原因以及分析处理

    5. 使用WeakReference和SoftReference: WeakReference和SoftReference可以帮助开发者更好地管理应用程序中的对象生命周期。 OOM错误的常见解决方法 1. 使用System.gc():System.gc()可以强制垃圾回收器回收垃圾...

    Java引用总结--StrongReference、SoftReference、WeakReference、PhantomRef

    Java从1.2版本开始引入了四种引用,分别是强引用(StrongReference)、软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference)。这四种引用的级别由高到低依次为:强引用 &gt; 软引用 &gt; 弱引用...

Global site tag (gtag.js) - Google Analytics