`

关于SoftReference与WeakReference的理解

JVM 
阅读更多
        正常来说,传统的JAVA引用,如
public void doSomeThing(){
    User user = new User();
    ...
}


       当方法doSomeThing方法结束时,对象user的引用丢失,其所占的空间将由JVM在下次垃圾回收时收回。如果我们将user对象的引用保存在一个全局的HashMap中,如
Map map = new HashMap();
public void doSomeThing(){
    User user = new User();
    map.put("user",user);
}


        此时,user对象由于在map中保存了引用,只要这个引用存在,那么JVM永远也不会收回user对象所占用的内存。
         这样的内存管理机制相信大家都耳熟能详了,在绝大多数情况下,这种解决方案都是非常完美的。但在某些情况下,却有些不便。好比如对于缓存而言,当user对象使用之后,我们希望保留其引用以供下次需要的时候可以重复使用,但又不希望其引用一直存在,如果那样,随着时间的推移,有限的空间将会被这些数据消耗殆尽。最好的方式莫过于一种方式,可以在对象没有被垃圾回收器回收之前依然可以访问,当垃圾回收器启动时,如果此对象没有其它对象引用,则按常规对其进行回收。
         SoftReference,WeakReference与PhantomReference为上面的思路提供了有力支持。
         这三种类型的引用属于“非持续性引用”,也就是说,这种引用关系并非持续存在,它们所代表的引用的生命周期与JVM的运行密切相关,而并非传统意义上的引用一样依赖于编码阶段的预先规划。
        SoftReference的例子:
SoftReference ref;
public void doSomeThing(){
User user = new User();
ref = new SoftReference(user);
}
public void doAnotherThing(){
User user = (User)ref.get();//通过SoftReference获得对象引用
System.out.println(user.getName());
}

        假设我们先执行了doSomeThing方法,产生了一个User对象,并为其创建了一个SoftReference引用。之后的某个时刻,我们调用了doAnotherThing方法,并通过SoftReference获取User对象的引用。此时我们是否还能取得user对象的引用?这要看JVM的运行情况。对于SoftReference而言,只有当目前内存不足的情况下,JVM在垃圾回收时才会收回其包含的引用(JVM并不是只有在内存不足的情况下才会启动垃圾回收器,具体什么时候启动得看具体版本JVM的垃圾回收策略)。这里可能出现两种情况
  • JVM目前还未出现过因内存不足所引起的垃圾回收,user对象的引用可以通过SoftReference从JVM Heap中收回。
  • JVM已经因为内存不足启动了垃圾回收机制,SoftReference所包含的user对象的引用被JVM所废弃。此时ref.get方法将返回一个空引用(null),对于上面的代码而言,也就意味着这里可能抛出一个NullPointerException。


       WeakReference比SoftReference在引用的维持性上来看更加微弱。无需等到内存不足的情况,只要JVM启动了垃圾回收机制,那么WeakReference所对应的对象就将被JVM回收。也就是说,相对SoftReference而言,WeakReference被JVM回收的概率更大。
       
        PhantomReference 比WeakReference 的引用维持性更弱。与WeakReference 和SoftReference不同,PhantomReference所引用的对象几乎无法被回收重用。它指向的对象实际上已经被JVM销毁(finalize方法已经被执行),只是暂时还没被垃圾回收器收回而已。PhantomReference主要用于辅助对象的销毁过程,在实际应用层研发中,几乎不会涉及。
分享到:
评论

相关推荐

    redis基础.rar

    周期无法控制可以采用SoftReference,WeakReference,PhantomReference这三种对象来执行(看了Ibatis的缓存机制才发现JDK居然还提供了PhantomReference这玩意儿,得恶补基础啊),这三种都是弱引用,区别在于强度...

    深入探讨 java.lang.ref 包1

    Java.lang.ref 包是 Java 类库中的一个重要组成部分,它包含了与垃圾回收机制密切相关的引用类。这些引用类的设计允许开发者在特定条件下控制对象的生命周期,尤其是在处理缓存、大型数据结构或者避免内存泄漏时显得...

    详解Java弱引用(WeakReference)的理解与使用

    Java 弱引用(WeakReference)的理解与使用 Java 中的弱引用(WeakReference)是一种特殊的引用类型,它可以帮助我们更好地管理内存和避免内存泄漏。在 Java 中,当一个对象被创建时,它被放在堆(Heap)中。当垃圾...

    android大位图二次采样处理三

    3. 使用软引用或弱引用:通过SoftReference或WeakReference持有Bitmap对象,帮助垃圾回收器更好地管理内存。 总结,大位图的二次采样处理是Android开发中解决内存问题的关键技术。开发者需要理解其原理,掌握计算...

    深入探讨 java-lang-ref 包.docx

    弱引用的使用方式与SoftReference类似,通过构造方法创建弱引用实例,并通过get()方法获取对象。当对象被回收后,get()方法同样会返回null。 清单 3. WeakReference usage WeakReference<Bean> beanRef = new ...

    博客 工作中遇到的Android内存优化问题demo

    对于那些可能引起内存泄漏的引用,可以考虑使用WeakReference或SoftReference。WeakReference在对象无其他强引用时会立即被回收,而SoftReference在系统内存紧张时才会被回收。 8. 观察者模式与内存泄漏: 注册...

    java虚拟机垃圾回收详解.docx

    Java提供了几种不同类型的引用,如SoftReference和WeakReference,来帮助管理对象的生命周期。SoftReference会在系统即将发生内存溢出之前才释放引用的对象,而WeakReference则会在GC发现对象不可达时立即释放。这些...

    图片下载以及内存处理防OOM.zip

    4. 载入Bitmap时使用SoftReference或WeakReference:这样在内存不足时,系统可以优先回收这些对象,降低OOM风险。 5. 使用内存和磁盘缓存:将图片保存到LRU Cache(最近最少使用)内存缓存和File Cache(文件缓存)...

    Android例子源码仿oom的三例瀑布流源码

    - **使用软引用和弱引用**:通过使用SoftReference和WeakReference,可以在内存不足时自动清除引用对象,防止内存泄漏。 - **LruCache**:Android提供的Least Recently Used缓存策略,用于缓存Bitmap或其他对象,...

    视频图片处理

    另外,使用SoftReference或WeakReference来存储Bitmap,可以在内存紧张时自动释放内存。此外,使用内存池和复用策略可以降低内存分配和回收的开销。对于频繁加载和显示图片的场景,如瀑布流或网格布局,还可以利用...

    安卓listview相关相关-listview获取网络图片缓存优化.zip

    在Android中,我们可以使用SoftReference或WeakReference来创建内存缓存,避免内存泄漏。对于磁盘缓存,可以使用开源库如Android Universal Image Loader (UIL)、Picasso或Glide,它们都提供了内置的缓存管理。 以...

    图片截取最新demo

    此外,使用SoftReference或WeakReference存储Bitmap对象,也能在内存紧张时自动释放内存。 3. 分辨率适配:不同的设备可能具有不同分辨率的屏幕,因此图片截取功能需要确保在所有设备上都能正常工作。一种常见方法...

    安卓Android源码——(Bitmap位图渲染与操作).zip

    - **Bitmap内存优化**:为了防止内存溢出,开发者需要合理管理Bitmap,如使用BitmapFactory.Options进行解码时指定缩放比例,或者使用SoftReference、WeakReference来缓存Bitmap。 3. **加载Bitmap**: - **从...

    Android 图片浏览器

    - SoftReference和WeakReference:对于内存敏感的应用,可以使用这些引用类型来管理Bitmap对象,防止内存泄漏,但需要注意它们并不保证在内存不足时一定会释放。 - 使用池化技术:通过BitmapPool回收和重用Bitmap...

    安卓Android源码——listview实现图片的异步加载.rar

    3. **内存缓存与磁盘缓存**: 为了提高性能,我们可以使用内存缓存(如SoftReference或WeakReference)和磁盘缓存(如LruCache或DiskLruCache)来存储已下载的图片。这样,再次需要同一图片时,可以从缓存中直接获取...

    拓胜技术专家教你如何深入理解Java四种引用类型

    Java中的四种引用类型是Java内存管理的重要组成部分,它们分别是强引用(StrongReference)、软引用(SoftReference)、弱引用(WeakReference)和虚引用(PhantomReference)。每种引用类型具有不同的特点和用途,...

    知识共享-Android之ListView滑动加载、软缓存、懒加载(雷惊风)

    此外,他还可能使用了某种形式的内存缓存机制,比如SoftReference或WeakReference,来保存ListView的项,只有在需要时才加载和绘制。懒加载的实现可能在Adapter的getView()方法中,只在列表项即将可见时加载对应的...

    图片缩放防止OOM

    2. **使用软引用或弱引用**:通过SoftReference或WeakReference持有Bitmap,允许垃圾回收器在内存不足时自动清理。 3. **使用内存池**:如PooledBitmap或LruCache,复用Bitmap对象,减少内存分配和释放的开销。 五...

    图片的三级缓存的使用

    同时,也可以选择不同的缓存实现,比如使用其他内存缓存库(如SoftReference或WeakReference)替代LruCache,或者定制自己的磁盘缓存策略。 六、优化与注意事项 1. 图片压缩:为了避免内存溢出,可以在加载图片前...

Global site tag (gtag.js) - Google Analytics