贝壳找房安卓端用Glide替换Picasso

2019 年 9 月 24 日

贝壳找房安卓端用Glide替换Picasso

近期贝壳找房安卓app在测试时发现报了OOM异常(即内存溢出),主要原因是图片占用内存空间过大。


操作步骤:打开贝壳找房,设置城市为“徐州”, 然后点击“二手房”图标进入“二手房列表页”, 向上滑动列表。



使用 Picasso



使用 Glide


上图是 Android Profiler 抓取的运行时内存, 使用 Picasso 时 Java 堆占用了 220.7M 字节, 使用 Glide 时 Java 堆占用了 85.8M。 直观上内存使用减少了一半。


Android8.0 及后续版本将 Bitmap 缓存在 Native 层, 理论上不会因为缓存图片导致 OOM; 而贝壳找房安卓 app 用户 Android8.0 以下占比 64%左右, 优化图片内存管理对这部分用户有意义。


改造成本


因为 Glide 比 Picasso 多了一个 Context 参数, 所有原来调用 Picasso 方法的地方都要修改。



使用 Glide


二手房业务都使用 LJImageLoader.java 显示图片, 只需要扩展方法加个 Context 参数, 调用时多传入一个 context 即可。


原理


Glide 在内存上使用二级缓存, 即当前正在使用的 activeResources(其实就是个 map,保存了图片的弱引用)和 LruCache(界面未显示的图片)。 在测试机魅族上 LruCache 默认只有 16M 字节, 而 Picasso 的 LruCache 在 160M 左右。


列表向上滑动时观察内存基本不变, 这是因为 Glide 及时回收了内存。



滑动 listview/recyclerview



复用 item 使用相同 ImageView 显示图片时会先释放其在 Glide 中的资源


因为 ListView 复用了 view,在数据不变情况下,内存中 ListView 缓存的 itemView 个数是固定的, 从而 Glide 的 activeResources 缓存的个数也是固定的。 前提:ListView 数据个数很多且要向上滑动一下。



对于 ListView 滑动时 activeResources 数量是不变的


在滑动列表时,将移出屏幕 item 的图片从 activeResources 中移除,并添加到 LruCache 中, 如果 LruCache 达到上限则自动清理。


Glide 比 Picasso 的 2 个优势:


1、因为 Glide 支持 Activity/Fragment 的生命周期, Glide 在生命周期 onStart 函数里注册连接状态变化广播并继续处理当前界面图片任务; 在生命周期 onStop 函数里取消注册连接状态广播并暂停处理当前界面图片任务; 在生命周期 onDestroy 函数里将当前界面使用的 activeResources 里的资源移出并添加到 LruCache 中。


2、当前 Activity A 有很多个图片, 这时再启动 Activity B、C、D, 虚拟机可能会 gc 隐藏的 activity,从而释放当前 app 的内存。


展望


安卓主流图片三方框架 Glide、Picasso、Fresco 各有特点, 而 Glide 是谷歌推荐的图片库。 贝壳找房 app 安卓端用 Glide 替换 Picasso 的成本较小, 收益是 64%使用 android8.0 以下用户不再出现 OOM 问题。


作者介绍:


高瑞,贝壳找房 Android 工程师,目前负责贝壳找房 app 安卓端研发工作。


本文转载自公众号贝壳产品技术(ID:gh_9afeb423f390)。


原文链接:


https://mp.weixin.qq.com/s/kOFRvRANG77qWmz3YSPIfw


2019 年 9 月 24 日 10:18479

评论

发布
暂无评论
发现更多内容

Spring Boot 如何快速实现定时任务

田维常

spring Boot Starter

哭了,前阿里P8见我spring太烂,把系列合集甩在了我脸上

周老师

scrapy学习之爬虫练习平台爬取

LLLibra146

爬虫 python 爬虫 Scrapy

复盘逆袭之路!三个月时间深造,怒斩拼多多、字节、蚂蚁金服破50W年薪Offer(含自学路线图)

Java架构追梦

Java 学习 架构 面试 数据结构与算法

芯片破壁者(十九):显卡的战国与帝国

脑极体

【原创】Spring Boot集成Redis的玩法

田维常

spring Boot Starter

【原创】Spring Boot 集成Spring Data JPA的玩法

田维常

spring Boot Starter

【原创】Spring Boot 如何手写stater

田维常

spring Boot Starter

一站式低延迟直播连麦解决方案

anyRTC开发者

音视频 WebRTC 直播 RTC sdk

Scrapy中process_request返回request和None的区别

LLLibra146

Python 爬虫 python 爬虫 Scrapy

OpenShift 4 监控技术栈解析

东风微鸣

Kubernetes Prometheus openshift 可观察性 Thanos

DDIA 读书笔记(4)多节点数据复制方案

莫黎

读书笔记

智能驾驶看湘江:中国智能网联汽车产业的“长沙样本”

脑极体

数据库JDBC:PreparedStatement

大规模数据处理学习者

JDBC SQL预处理 PrepareStatement

聊点缓存——Part 1

姜雨生

redis 缓存

专业级沙箱与恶意样本的自动化分析

京东智联云开发者

云计算 监控 虚拟化

scrapy学习之爬虫练习平台3

LLLibra146

Python 爬虫 python 爬虫 Scrapy

scrapy学习之爬虫练习平台4

LLLibra146

Python 爬虫 python 爬虫 Scrapy

【原创】Spring Boot集成Mybatis的玩法

田维常

spring Boot Starter

【原创】SpringBoot快速整合Thymeleaf模板引擎

田维常

spring Boot Starter

想不通(关于人生的突发奇想)

干啥啥不行的赢

YOLODet 最强PyTorch版的YOLOv5、YOLOv4、PP-YOLO、YOLOv3复现

wuzhihao7788

学习 AI 目标追踪

架构师训练营第七周作业

邓昀垚

Spring Boot 集成 Druid 监控数据源

田维常

spring Boot Starter

【原创】Spring Boot一口气说自动装配与案例

田维常

spring Boot Starter

【原创】Spring Boot 过滤器、监听器、拦截器的使用

田维常

spring Boot Starter

【原创】Spring Boot终极篇《上》

田维常

spring Boot Starter

YOLODet--YOLO系列网络结构图(YOLOv5,YOLOv4,PPYOLO,YOLOv3)

wuzhihao7788

学习 AI 目标追踪

【原创】Spring Boot终极篇《下》

田维常

spring Boot Starter

scrapy学习之爬虫练习平台2

LLLibra146

Python 爬虫 python 爬虫 Scrapy

scrapy学习之爬虫练习平台5

LLLibra146

Python 爬虫 python 爬虫 Scrapy

贝壳找房安卓端用Glide替换Picasso-InfoQ