Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2019-11-26:谈一谈Glide的缓存机制? #197

Open
MoJieBlog opened this issue Nov 26, 2019 · 6 comments
Open

2019-11-26:谈一谈Glide的缓存机制? #197

MoJieBlog opened this issue Nov 26, 2019 · 6 comments

Comments

@MoJieBlog
Copy link
Collaborator

No description provided.

@lvasd
Copy link

lvasd commented Dec 4, 2019

郭霖大佬曾经基于glide 3.X版本 写过 7 8篇关于glide的博客 现在虽然glide 4.X了 但是很多东西还是没变的

@twfx5
Copy link

twfx5 commented Dec 4, 2019

Glide的缓存机制,主要分为2种缓存,一种是内存缓存,一种是磁盘缓存。
使用内存缓存的原因是:防止应用重复将图片读入到内存,造成内存资源浪费。
使用磁盘缓存的原因是:防止应用重复的从网络或者其他地方下载和读取数据。

具体来讲,缓存分为加载和存储:
①当加载一张图片的时候,获取顺序:Lru算法缓存-》弱引用缓存-》磁盘缓存(如果设置了的话)。

当想要加载某张图片时,先去LruCache中寻找图片,如果LruCache中有,则直接取出来使用,并将该图片放入WeakReference中,如果LruCache中没有,则去WeakReference中寻找,如果WeakReference中有,则从WeakReference中取出图片使用,如果WeakReference中也没有图片,则从磁盘缓存/网络中加载图片。

②将缓存图片的时候,写入顺序:弱引用缓存-》Lru算法缓存-》磁盘缓存中。

当图片不存在的时候,先从网络下载图片,然后将图片存入弱引用中,glide会采用一个acquired(int)变量用来记录图片被引用的次数, 当acquired变量大于0的时候,说明图片正在使用中,也就是将图片放到弱引用缓存当中;如果acquired变量等于0了,说明图片已经不再被使用了,那么此时会调用方法来释放资源,首先会将缓存图片从弱引用中移除,然后再将它put到LruResourceCache当中。这样也就实现了正在使用中的图片使用弱引用来进行缓存,不在使用中的图片使用LruCache来进行缓存的功能。

另:从Glide4.x开始,读取图片的顺序有所改变:弱引用缓存-》Lru算法缓存-》磁盘缓存

@manondidi
Copy link

那我来说说glide4 的缓存机制吧
glide4 缓存主要分为三个 activiteResources(弱引用缓存) MemoryCache(Lru缓存) DiskCache(磁盘缓存) 还有一个http网络缓存, 不多做介绍

首先弱引用缓存代表的是当前正在使用的缓存, 请求图片之后 会分为两个步骤, 1.进入磁盘缓存,2进入弱引用缓存。 在弱引用缓存中使用一个计数器来维护当前资源的是否被使用,如果计数器=0说明当前资源已经不被使用了,则进入Lru缓存,Lru缓存是glide使用linkhashmap来维护的,如果lru满了则删除最长时间未使用的。
如果一个资源加载的时候在弱引用缓存中找不到,就会到lru缓存中查找,如果没找到就去磁盘缓存找,不管在lru中找到 还是在磁盘中找到, 都会把命中的缓存,放在弱引用缓存中.

glide设计的三层缓存模型, 其中内存缓存 减轻了磁盘缓存的压力,避免io操作,而弱引用缓存则减轻了 lru缓存的压力,避免lru过满导致频繁gc,并且提高查找效率

另外再说下 glide4 五种缓存策略 data source all no automic
data则是缓存住原始图片资源, source则是缓存住变换后的资源(glide 会针对imageview的大小对图片预先变换,避免小imageview加载大图片浪费内存)
all 就是两种都缓存, no就是不缓存 ,automiic 则比较特殊,会缓存data 根据图片的编码 自行判断是否缓存resource

@yline
Copy link

yline commented Feb 14, 2020

配上代码来说,统一的key,依据key去找;代码在Engine中
1,Hashmap<Key, ResourceWeakReference>,从弱引用中获取,直接内存缓存。系统内存不足时,允许gc
2,Lrucache<Key, Resource>,Lrucache缓存,超过缓存额度时,将最久未使用的内存删除。使用内存缓存,强引用
3,Hashmap<Key, EngineJob>,从网络中获取图片,同时如果多个相同的图片请求触发,避免相同的网络重复请求
4,创建新的LoadStatus(cb, EngineJob),从网络中获取图片

总结:弱引用 -> Lrucache -> 网络防重复请求 -> 网络请求

@mlinqirong
Copy link

1,为什么使用Glide
Glide可以处理多种图片格式缓存 如:gif jpg png webp 缩略图
Glide使用了三种缓存机制 活动缓存(HashMap软引用) 内存缓存(LruCache)硬盘缓存(DiskLruCache)
Glide创建一个空的Fragment 来做生命周期管理 防止内存溢出
Glide缓存机制
加载图片通过算法生成key先去活动缓存获取 如果活动缓存有就直接显示 没有就去内存缓存中去寻找 内存中如果有移除内存中缓存添加到活动缓存中展示 内存缓存如果没有则去磁盘缓存中 磁盘缓存中有添加到活动缓存中显示 磁盘缓存中没有直接去网络中下载 网络中下载完成展示图片并缓存到硬盘缓存中 Glide创建一个空的Fragment来管理生命周期 如果Activity被关闭把活动缓存的添加到内存缓存中 活动缓存满的话未被使用的缓存移动到内存缓存中

@mlinqirong
Copy link

1,为什么使用Glide
Glide可以处理多种图片格式缓存 如:gif jpg png webp 缩略图
Glide使用了三种缓存机制 活动缓存(HashMap软引用) 内存缓存(LruCache LinkedHashMap强引用)硬盘缓存(DiskLruCache)
Glide创建一个空的Fragment 来做生命周期管理 防止内存溢出
Glide缓存机制
活动缓存(HashMap软引用) -》内存缓存(LruCache LinkedHashMap强引用)-》硬盘缓存(DiskLruCache)-》外置加载(网络,IO流)
加载图片通过算法生成key先去活动缓存获取 如果活动缓存有就直接显示 没有就去内存缓存中去寻找 内存中如果有移除内存中缓存添加到活动缓存中展示 内存缓存如果没有则去磁盘缓存中 磁盘缓存中有添加到活动缓存中显示 磁盘缓存中没有直接去网络中下载 网络中下载完成展示图片并缓存到硬盘缓存中 Glide创建一个空的Fragment来管理生命周期 如果Activity被关闭把活动缓存的添加到内存缓存中 活动缓存满的话未被使用的缓存移动到内存缓存中

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants