美文网首页Android专题android
图片加载<第四篇>:学会使用软引用解决OOM问题

图片加载<第四篇>:学会使用软引用解决OOM问题

作者: NoBugException | 来源:发表于2019-05-17 14:24 被阅读23次

学会使用软引用和弱引用可以进一步优化内存泄漏问题。

本文主要让大家了解什么叫强引用软引用弱引用虚引用以及怎么使用。

(1)强引用(StrongReference)
Object object = new Object();
String name= "zhangsan";

强引用在项目中很常见,程序猿已经习惯性的使用强引用了,以上两句简单代码就是所谓的强引用。

当强引用对象占用的内存超过最大可分配内存时,就是发生OOM。

(2)软引用(SoftReference)

软引用是用来描述一些有用但并不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。

SoftReference<String> str1 = new SoftReference<>(new String("hello1"));
Log.d("aaa", "str:"+str1.get());

//可以将软引用存入引用队列
ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();
SoftReference<String> str2 = new SoftReference<>(new String("hello2"), referenceQueue);
Log.d("aaa", "str:"+str2.get());
(3)弱引用(WeakReference)

弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,都会回收被弱引用关联的对象。在java中,用java.lang.ref.WeakReference类来表示。

WeakReference<String> str = new WeakReference<>(new String("hello"));
Log.d("aaa", "str:"+str.get());
System.gc();
Log.d("aaa", "str:"+str.get());

结果为:

图片.png
(4)虚引用(PhantomReference)

虚引用和前面的软引用、弱引用不同,它并不影响对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收。

要注意的是,虚引用必须和引用队列关联使用,当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会把这个虚引用加入到与之 关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

ReferenceQueue<String> queue = new ReferenceQueue<>();
PhantomReference<String> str = new PhantomReference<>(new String("hello"), queue);
Log.d("aaa", "str:"+str.get());

结果是:

图片.png
(5)如何使用软引用解决OOM问题

BitmapFactory.decodeFile()将图片转成bitmap,这句代码是非常消耗性能的,为了防止同一张图片频繁的转成bitmap,我们需要将bitmap存入缓存,代码如下:

private Map<String, Bitmap> bitmaps = new HashMap();

/**
 * 将Bitmap保存到缓存
 * @param path 文件路径
 * @param bitmap 文件的bitmap对象
 */
private void addBitmapToCache(String path, Bitmap bitmap){
    bitmaps.put(path, bitmap);
}

/**
 * 获取缓存中的bitmap
 * @param path
 * @return
 */
private Bitmap getBitmap(String path){
    Bitmap bitmap = bitmaps.get(path);
    return bitmap;
}

这个想法不错,但是bitmap是非常占用内存的,如果缓存容器中存放多个bitmap对象很有可能造成OOM问题,解决OOM问题需要引用软引用或者弱引用软引用只有在内存不足的时候JVM才会回收该对象,弱引用无论内存是否充足,JVM进行垃圾回收时,都会回收被关联的对象。这里采用软引用较为适合。

private Map<String, SoftReference<Bitmap>> bitmaps = new HashMap();

/**
 * 将Bitmap保存到缓存
 * @param path 文件路径
 * @param bitmap 文件的bitmap对象
 */
private void addBitmapToCache(String path, Bitmap bitmap){
    bitmaps.put(path, new SoftReference<Bitmap>(bitmap));
}

/**
 * 获取缓存中的bitmap
 * @param path
 * @return
 */
private Bitmap getBitmap(String path){

    //获取软引用
    SoftReference<Bitmap> softReference = bitmaps.get(path);

    if(softReference == null){
        return null;
    }

    Bitmap bitmap = softReference.get();
    return bitmap;
}

以上代码是一个不错的方案,当获取的bitmap为null时,就重新在本地解码图片。

相关文章

  • 图片加载<第四篇>:学会使用软引用解决OOM问题

    学会使用软引用和弱引用可以进一步优化内存泄漏问题。 本文主要让大家了解什么叫强引用、软引用、弱引用、虚引用以及怎么...

  • 性能优化

    问题:setImageResource()造成卡顿和oom解决方案:使用图片加载框架Glide加载图片

  • Android内存溢出

    如何避免OOM 1. 图片过大导致OOM(解决方法) 方法1: 等比例缩小图片方法2:对图片采用软引用,及时地进行...

  • 内存分配与回收

    OOM [Out of Memory] 内存溢出 解决办法:1、等比例缩小图片2、对图片采用软引用,及时进行 re...

  • 2017面试题总结

    一、如何避免OOM异常 解决方法: 方法 1: 等比例缩小图片 方法 2:对图片采用软引用,及时地进行 recyl...

  • 用BitmapFactory.decodeStream()方法计

    在学习图片加载时图片很大的时候直接加载到内存或则直接原图绘制到 ImageView中会导致OOM问题; 解决思路是...

  • Mybatis中特殊符号转移

    1. 写法1 原符号替换符号<<<=<=>>>=>=<><>&&'&a...

  • Android-Bitmap优化

    概述 在日常开发中我们经常遇到加载图片报出oom的错误,我们要解决这个问题,首先要明白oom代表out of me...

  • 解决图片加载oom

    几个知识点 方案一: 读取图片时注意方法的调用,适当压缩 方案二:在适当的时候及时回收图片占用的内存通常Activ...

  • test

    <script>alert(1);</script>

网友评论

    本文标题:图片加载<第四篇>:学会使用软引用解决OOM问题

    本文链接:https://www.haomeiwen.com/subject/srvmaqtx.html