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

两年前部落项目接入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还是保持原配置,这里需要结合具体业务进行设置。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏walterlv - 吕毅的博客

.NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)

发布于 2018-08-19 12:42 更新于 2018-08...

2021
来自专栏企鹅号快讯

一次垃圾邮件的分析

本篇文章来自同事对一次垃圾邮件的分析: 上周一(12月4号),朋友给我转发了一封垃圾邮件,邮件里面附带一个word文档,我们俩都是搞信安,自然察觉一丝危险的气味...

2027
来自专栏我就是马云飞

LiveDate和LifeRegistry的协同操作

前言 这个是Android Architecture Components(简称AAC)的第三篇,之前的两篇 文章分别介绍了Lifecycle和ViewMode...

2008
来自专栏静晴轩

Gulp折腾之路(II)

前段时间折腾Gulp,主要是搜寻一些插件,组合之以优化前端开发流程。这段折腾历程除了达成所愿外,给予最大的收获是:只要你想实现某功能,基本就已有对应插件供使用;...

3425
来自专栏腾讯Bugly的专栏

​ 《企鹅电竞weex实践—— iOS SDK的小九九》

| 导语 企鹅电竞iOS端在3.2版本接入了Weex,感受了一把前端的代码原生的体验。本文从WeexSDK源码出发,主要介绍了Weex在iOS侧的框架结构以及大...

4775
来自专栏何俊林

Android Multimedia框架总结(二十)MediaCodec状态图及Codec与输入/输出Buffer过程(附实例)

前言:前面几节都是介绍Camera2相关,对于Camera2预览把图像显示在SurfaceView上,还有录像时,时时刷新当前图像区域。追溯到最早介绍的Medi...

2958
来自专栏Python中文社区

用Python将word文件转换成html

序 最近公司一个客户大大购买了一堆医疗健康方面的科普文章,希望能放到我们正在开发的健康档案管理软件上。客户大大说,要智能推送!要掌握节奏!要深度学习!要让用户...

6056
来自专栏腾讯Bugly的专栏

Android UI:机智的远程动态更新策略

1 问题描述 做过Android开发的人都遇到过这样的问题:随着需求的变化,某些入口界面通常会出现 UI的增加、减少、内容变化、以及跳转界面发生变化等问题。每次...

3459
来自专栏后台开发+音视频+ffmpeg

c++ 时间轮定时器实现

之所以写这篇文章,是在一篇博客中看到了时间轮定时器这个东西,感觉很是惊艳。

8894
来自专栏xingoo, 一个梦想做发明家的程序员

Spark DataFrame写入HBase的常用方式

Spark是目前最流行的分布式计算框架,而HBase则是在HDFS之上的列式分布式存储引擎,基于Spark做离线或者实时计算,数据结果保存在HBase中是目前...

7705

扫码关注云+社区