前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Fresco 4.X和5.X内存分析

Fresco 4.X和5.X内存分析

作者头像
MelonTeam
发布2018-01-04 15:43:57
1.3K0
发布2018-01-04 15:43:57
举报
文章被收录于专栏:MelonTeam专栏MelonTeam专栏

两年前部落项目接入Fresco的时候,那时候主流机型还是4.X。Fresco在4.X的机器的内存性能很好,Bitmap存在Ashmem(匿名共享内存)层里面的,对应用的内存缓存的压力不大。

4.X系统的Fresco

安卓系统的Ashmem层这里不做过多介绍,我们来看下缓存到Ashmem最后一个JAVA函数。通过注释发现,只有purgeable bitmap才能生效,我们来看下purgeable bitmap究竟是什么。

inPurgeable这个属性标识这个Bitmap是否是可清除的,设置为true之后,该系统会自动把Bitmap存储在Ashmem中, 当系统存储不足的时候会被回收,等到需要的时候,会在主线程重新进行解码,然而这种解码是会造成主线程卡顿的。

为了解决这种卡顿,Fresco调用AndroidBitmap_lockPixels这个native方法锁住这块内存,锁住这块内存之后GC便不会对该内存生效,因此就不会有在主线程重编码的卡顿问题了。Fresco需要自己进行这块内存的管理。Fresco里面只使用了pin方法,unpin操作通过Bitmap的recycle的操作来完成,如果Bitmap最后没有释放,那么会造成内存泄漏,影响系统的运行状况。所幸的是,Fresco的引用计数方式已经很完善,并且当SimpleDraweeView onDetachWindow的时候也会做释放操作,在这种情况下内存交给Fresco还是挺令人放心的。

5.X以上系统的Fresco

然而purgeable bitmap引起主线程卡顿的这一缺陷最终使得谷歌在5.0以上的系统废弃了它,所以Fresco在5.0以上系统再也没法使用Ashmem层了,Bitmap的内存压力重新回到了Java Heap中。随着主流操作系统逐渐趋向于5.0,6.0,Fresco导致的OOM问题也趋于严重。

经过对Fresco内存缓存系统的分析,我们可以看到CountingMemoryCache这个内存缓存类里面实际上是包含两块内存区域的。

mExclusiveEntries和mCacheEntries都是基础Lru策略进行存储管理,mExclusiveEntries这块存储是用来缓存没有被使用等待回收的Bitmap内存的,也就是说,如果一个Bitmap的引用计数为0,他会进入到mExclusiveEntries中,被mExclusiveEntries lru淘汰的Bitmap才会被真正的释放。

然而,坑爹的是,默认配置中对这块缓存的大小和数量限制简直可以说是没有,之前代码内限制都是Integer.MAX_VALUE,在DefaultBitmapMemoryCacheParamsSupplier这个类里面对这块内存的配置项进行限制,对5.0以上Fresco的内存优化效果巨大,目前我这里的限制是(150,17M),mCacheEntries还是保持原配置,这里需要结合具体业务进行设置。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4.X系统的Fresco
  • 5.X以上系统的Fresco
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档