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 条评论
登录 后参与评论

相关文章

来自专栏Flutter入门

RecyclerView 源码分析-开编

看了又看,任然对其一知半解。用了又用,发现其真的太美。RecyclerView的设计和书写实在是太惊艳了,日常又使用的相当频繁。虽然之前就看过其他的源码分析,故...

1012
来自专栏祝威廉

Elasticsearch 漫谈

之前在研究ElasticSearch的时候,发现竟然已经有七篇文章了。这些文章通常都是遇到了问题,于是去研读相关代码,试图搞清楚里面的机制,顺带记录下来而成文的...

1274
来自专栏恰同学骚年

《你必须知道的.NET》读书笔记一:小OO有大智慧

此篇已收录至《你必须知道的.Net》读书笔记目录贴,点击访问该目录可以获取更多内容。

382
来自专栏我是攻城师

为什么用 Java:一个 Python 程序员告诉你

3429
来自专栏杨建荣的学习笔记

一个95后开发者关于消息发送的实践

这篇文章最开始投给我的时候,没有引起太多的重视,但是看了内容之后,真是被里面的细节吸引了。

810
来自专栏互联网杂技

通俗讲解:缓存、缓存算法和缓存框架

1 引言 我们都听过 cache,当你问他们是什么是缓存的时候,他们会给你一个完美的答案,可是他们不知道缓存是怎么构建的,或者没有告诉你应该采用什么标准去选择缓...

3216
来自专栏向治洪

hello Kotlin

1.1 Kotlin的身世 写了许久 Java,有没有发现其实你写了太多冗余的代码? 后来你体验了一下 Python,有没有觉得不写分号的感觉真是超级爽? 你虽...

1795
来自专栏腾讯Bugly的专栏

Android开发必备知识:为什么说Kotlin值得一试

1、Hello, Kotlin 1.1 Kotlin的身世 写了许久 Java,有没有发现其实你写了太多冗余的代码? 后来你体验了一下 Python,有没有觉得...

4119
来自专栏ImportSource

设计WeakReference的那段日子

当你遇到要开发一个缓存,并且是短期内就过期的那种缓存的需求?你会怎么实现呢? Mark Reinhold看着1.1版的Java代码沉思着,最近社区传来1.1版本...

2736
来自专栏Flutter入门到实战

最全的BAT大厂面试题整理

版权声明:本文为博主原创文章,未经博主允许不得转载。https://www.jianshu.com/p/c70989bd5f29

772

扫码关注云+社区