安卓开发中Glide的缓存机制
在使用Glide加载图片时,Glide会在一个新的图片请求之前检查再决定是否需要在原始资源数据中取出资源常用算法——算法是一种常用的缓存逐出策略,用于在内存受限的情况下管理缓存。当缓存达到其最大容量时,LRU算法会淘汰,以便为新项腾出空间。
在使用Glide加载图片时,Glide会在一个新的图片请求之前检查多级缓存再决定是否需要在原始资源数据中取出资源
常用算法——LRU(Least Recently Used,最近最少使用)算法是一种常用的缓存逐出策略,用于在内存受限的情况下管理缓存。当缓存达到其最大容量时,LRU算法会淘汰最长时间未被使用的项,以便为新项腾出空间。
Glide二级缓存结构
Glide获取资源的执行流程
具体执行流程图如下:
Glide缓存机制
Glide使用了Active Cache(活动缓存弱引用)+Memory Cache(内存缓存Lru算法)+Disk Cache(磁盘缓存Lru算法)。
关于弱引用在文章后面会有说明
注意: Active Cache + Memory Cache是内存缓存,都属于运行时缓存,且互斥(同一张图片不会同时缓存在活动缓存和内存缓存中,应用被杀死后将不存在。)
1、活动缓存 (Active Cache)
如果图片正在被使用,则这个图片会被Glide加入到这个活动缓存中。
什么是正在被使用?比如进入某Activity展示一张图片,展示的时候会把这个图片加入到活动缓存中,退出Activity时,会从活动缓存中移除,移除的图片资源不会立即销毁,而是加入到内存缓存。
如果在加载图片的时候:
- 发现活动缓存中没有,会在内存缓存进行查找。
- 资源存在的话,Glide会把对应的资源从内存缓存中移除,加入到活动缓存中去。
这样可以避免因为达到内存缓存最大值或者系统内存压力导致的内存缓存清理,从而释放掉活动资源中的图片。这句话是什么意思?如果一张图片资源同时被活动缓存和内存缓存所引用的话,当内存缓存的数量达到所设定的最大值后,会根据LRU算法移除图片资源,进行内存释放,如果所释放的图片资源也存在于活动资源的话,因为此图片资源正在使用,被释放后就会引起空指针异常的错误
2、内存缓存 (Memory cache)
内存缓存默认使用LRU(缓存淘汰算法/最近最少使用算法),当资源从活动资源移除的时候,会加入内存缓存。使用图片的时候会主动从此缓存移除,加入活动资源缓存。
内存缓存是快速访问图片的关键,因为它允许Glide避免重复解码和渲染操作
3、资源缓存(DiskCache - Resource)
资源缓存所缓存的资源是经过解码后的图片,如果再使用就不需要再去进行解码配置(BitmapFactory.Options),加快获得图片速度。
比如原图是一个100x100的ARGB_8888图片,在首次使用的时候需要的是50x50的RGB_565图片,那么Resource将50x50 RGB_565缓存下来,再次使用此图片的时候就可以从 Resource 获得。不需要去计算inSampleSize(缩放因子)。
4、原始缓存 (DiskCache - Data)
原始缓存通常指的是存储原始图片数据(如从网络下载的或从磁盘读取的未解码数据)的缓存。
在Glide中,原始数据可能会被缓存到磁盘上,以避免重复的网络请求或I/O操作。
5、Java中的四种引用方式
补充: GC,全称为 Garbage Collection(垃圾回收)
1.强引用(StrongReference)
- 使用最普遍的引用。
- 只要引用链没有断开,强引用就不会断开。当内存空间不足,抛出 OutOfMemoryError 终止程序也不会回收具有强引用的对象。
- 通过将对象设置为null来弱化引用,使其被回收
Object object = new Object();
String str = "scc";
//都是强引用
2.弱引用(WeakReference)
- 弱引用所指向的对象在下一次垃圾回收时会被回收,无论当前内存是否不足。
- 它们适用于监听器、临时缓存等场景,这些场景中的对象应该在不再需要时自动回收。
Map<Key, ResourceWeakReference> activeEngineResources = new HashMap<>();
//ResourceWeakReference弱引用
3.软引用(SoftReference)
- 如果对象只具有软引用,当内存不足时(即在发生垃圾回收之前),这些对象会被回收。
- 可以用来实现高速缓存(作用)--比如网页缓存、图片缓存
// 注意:wrf这个引用也是强引用,它是指向SoftReference这个对象的,
// 这里的软引用指的是指向new String("str")的引用,也就是SoftReference类中T
SoftReference<String> wrf = new SoftReference<String>(new String("str"));
4.虚引用(PhantomReference)
- 虚引用是最弱的一种引用,它们唯一的作用是在对象被回收后收到一个系统通知。
- 由于虚引用几乎不对对象的生命周期产生影响,它们很少被使用,一个典型的用途是在某些特定情况下进行资源的清理。
Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue();
PhantomReference reference = new PhantomReference(obj, queue);
//强引用对象滞空,保留软引用
obj = null;
参考文章:
Glide框架解析---缓存机制介绍及活动缓存 内存缓存 复用池相关类(一)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)