【Android】使用glide加载未知尺寸图片导致OOM问题的解决方案

问题:app中有一个Activity用于查看大图,最近出现了一些超大图(内存占用超100M),导致app出现OOM导致的crash

背景:大图的来源中只给出了图片的url,除此之外再无任何信息。图片url提供方对于提供图片其他信息(如宽/高),成本较高,讨论之后有客户端自己进行处理。

 

1⃣️OOM产生的原因

内存占用量超过了vm能分配的最大内存量,或者一下子申请了一块非常大的内存(比如100M),虽然内存还有很大空间,但是无法一下腾出连续的一片内存进行分配,可能会导致内存溢出。

之前试了一下try-catch,发现是catch不住这种Error的,知乎上一篇回答安卓编程:可否用try-catch捕获Out Of Memory Error以避免其发生?说,try-catch只能catch住在try里面申请内存的变量抛出的Error,而且这次catch住了,下次还是会抛,所以用try-catch解决OOM的问题是不太可行的。

关于vm能分配的内存,android dalvik heap 浅析 这篇文章介绍的非常形象

(1) dalvik.vm.heapstartsize        初始分配的堆size

(2) dalvik.vm.heapgrowthlimit    受控app的极限堆size

(3) dalvik.vm.heapsize               不受控app的极限堆size
 

这三个值在不同手机上会有所不同,在build.prop文件里,可以查看 Android系统移植与调试之------->build.prop文件详细赏析

dalvik.vm.heapstartsize=5m	#单个应用程序分配的初始内存
dalvik.vm.heapgrowthlimit=48m	#单个应用程序最大内存限制,超过将被Kill,这或许是某些大体积程序闪退的原因
dalvik.vm.heapsize=256m  #dalvik的虚拟内存大小

我们可以通过在manifest中配置android:largeheap=true,可以让app申请的内存达到heapsize,这样app可用内存可以变多。但是这样相应的后果是每次gc的时间也会变长,导致性能变差,我们尽量要从“减少使用的内存”方向优化,避免占用更大的内存。

 

2⃣️图片占用内存的计算方式

图片占用的字节数 = 图片宽度(像素)* 图片高度(像素)* 单位像素占用字节数

其中图片的宽/高,glide在RequestListener的onSourceReady回调的GlideDrawable中,可以通过GlideDrawable.getIntrinsicWidth()和GlideDrawable.getIntrinsicHeight()获取,单位像素占用字节数根据ARGB方式进行计算,如config为Bitmap.Config.RGB_565表示:每个像素占16位,没有透明度,R-5,G-6&#

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值