Glide(Android)之Bitmap对象池

对象池,我们知道是存了对象的,将来可以复用,这样避免频繁地创建和回收常用对象,造成内存抖动,降低app的性能。

对于普通的对象来说,其本身占用内存很小,同时在放到对象池的时候,会对对象重置的,所以对象池不会关心对象个体的内存大小,只关心对象的数量。基本上有两种实现方案,数组和单链表,Android官方都有实现使用,Pools采用了数组,大小可以自己指定,Message采用了单链表,可以存50个message对象,如果对象池中对象满了,再放直接抛弃就行。具体可以看Glide(Android)之普通对象池

还有一种对象池,存的就不是普通对象了,是为了专门复用其内存的,比如Bitmap,所以此时的对象池关心的是内存大小,不再是对象个数。对于Bitmap地复用来说,比较复杂,不是说从Bitmap对象池中取出一个Bitmap就能复用。具体可以看Android之 Bitmap

Android官方给里例子是把复用的bitmap方法一个Set中,

(1)这样从Set取bitmap的时候就得遍历了,然后获取满足的bitmap(4.4之前和之后复用方式是不一样的),

(2)而且,对对象池大小没有管理。

(3)获取到可以复用的bitmap之后,需要从set中移除

在Glide进行了改进,采用了Lru 的map来存bitmap,这样通过key查找效率高,同时,还管理了对象池大小,满了抛弃不常用的,其实这样是合理的,因为不常用的没有必要放对象池,要不然就失去了对象池的意义。同时,还采用了一个map来记录,Config和Size,的个数count,如果获取到可以复用的bitmap,只需要count减1就可以,不需要真正把Bitmap中对象池拿掉。

下面这篇文章基本讲的很完整

Glide4.8源码拆解(五)BitmapPool从入门到放弃

说完了LruBitmapPool对象池,我们得说一些Glide中是怎么用的

首先复用Bitmap,要想复用肯定是找到合适的Bitmap,付给BitmapFactory.Options  的inBitmap,这个是在Downsampler中做的

  @TargetApi(Build.VERSION_CODES.O)
  private static void setInBitmap(
      BitmapFactory.Options options, BitmapPool bitmapPool, int width, int height) {
    @Nullable Bitmap.Config expectedConfig = null;
    // Avoid short circuiting, it appears to break on some devices.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      if (options.inPreferredConfig == Config.HARDWARE) {
        return;
      }
      // On API 26 outConfig may be null for some images even if the image is valid, can be decoded
      // and outWidth/outHeight/outColorSpace are populated (see b/71513049).
      expectedConfig = options.outConfig;
    }

    if (expectedConfig == null) {
      // We're going to guess that BitmapFactory will return us the config we're requesting. This
      // isn't always the case, even though our guesses tend to be conservative and prefer configs
      // of larger sizes so that the Bitmap will fit our image anyway. If we're wrong here and the
      // config we choose is too small, our initial decode will fail, but we will retry with no
      // inBitmap which will succeed so if we're wrong here, we're less efficient but still correct.
      expectedConfig = options.inPreferredConfig;
    }
    // BitmapFactory will clear out the Bitmap before writing to it, so getDirty is safe.
    options.inBitmap = bitmapPool.getDirty(width, height, expectedConfig);
  }

DownSampler里面也是很重要的一块内容,这篇文章不错,以后有机会看Glide4.8源码拆解(四)Bitmap解析之"下采样"浅析

回收是在不用的时候,有很多种情况

(1)ActiveResources中移除的时候,如果设置不放到MemoryCache中,最终会到BitmapPool里

(2)MemoryCache淘汰出来的,也会回收到Bitmap里面。

(3)其它出错的时候

发布了189 篇原创文章 · 获赞 25 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/lizhongyisailang/article/details/104811338