您好!欢迎来到爱源码

爱源码

热门搜索: 抖音快手短视频下载   

提高颤振内存利用率的方案(存储干货) 《互站网》

  • 时间:2022-10-25 01:48 编辑: 来源: 阅读:314
  • 扫一扫,手机访问
摘要:提高颤振内存利用率的方案(存储干货) 《互站网》
背景我们闲鱼使用的图片方案是自主研发的外部纹理方案:Android端创建SurfaceTexture,通过FlutterJNI注册到Flutter引擎中,最后将纹理id返回给Flutter应用层,Flutter应用层使用Texture Widget和textue id显示图片纹理。 纹理数据在安卓端。通过OpenGL将图像纹理写入SurfaceTexture,然后通过Flutter引擎中的共享内存将纹理数据传递到应用层,最后交给Skia进行渲染。 Alt text有一个问题:Flutter应用层的纹理数据没有缓存,每次都需要将位图数据重新渲染成纹理,然后交给Flutter应用层使用。 原生图像加载会缓存在内存中,Flutter提供的图像库本身也有缓存。这两个缓存相互隔离,占用大量内存空间。 而且,Flutter图片缓存基本都是存储本地资源图,而我们大部分的Flutter页面实际上都是从网络下载的外部纹理图片,导致缓存资源利用率低。 要分析以上三个问题,我们先抛开技术实现,假设处理这三个问题,最理想的解决方案是什么:纹理没有缓存,我们只要在应用层增加一个纹理的内存缓存就可以了。 当上层应用层缓存了纹理后,原生端位图的内存缓存也可以去掉,只保留图像资源的磁盘缓存。 整个App只有纹理缓存和Flutter的ImageCache。为了避免内存资源的浪费,将两个缓存合并为一个理想的处理方案:整个App只有一个内存缓存,可以同时缓存Flutter的Image Widget加载的纹理和图像数据。 处理方案ImageCache是官方提供的,所以我们无法摆脱,闲鱼App中也有少数地方使用了图片Widget。 现在,解决方案是在ImageCache中缓存纹理数据。 使用纹理时,先从imageCache中取出。 让我们看看现有的FLUTER图像加载逻辑以及图像是如何缓存的。Alt text从图中可以看出,加载FLUTER图片时,会调用ImageCache.putIfAbsent方法,当缓存缺失时,会使用传入的loader方法构造相应的imagestreamcompiler,imagestreamcompiler完成图片加载逻辑。 当缓存命中时,putIfAbsent方法会直接返回ImageStreamCompleter,它保存imageInfo,ImageWidget直接渲染ui。imageInfo的图像。 方案一:扩展ImageCache,缓存纹理ImageCache提供外部缓存方法。首先我们要根据这个方法的参数来构建相应的key、loader、ImageStreamCompleter,然后使用putIfAbsent方法进行缓存。 试了一下发现不行,如下图。当图片下载解码成功后,这个监听器方法会被回调。在这个方法中,图片将被存储在ImageCache的缓存队列Alt text中。这个侦听器回调有两个参数,ImageInfo存储图片数据ui。图像 Alt text我们的应用层无法构造ui。图像,因为这个类是在Flutter引擎底层完成图像解码后设置给应用层的。 应用层没有办法主动设置值。 这样一来,imageSize的值就无法在监听器中计算出来,自然也就无法存储在缓存中。 方案二:自己设置ImageCache。因为ImageCache的缓存队列是私有的,所以只有putIfAbsent方法可以在其中存储数据。 我们只有另外一个办法,从ImageCache的源代码入手,自己设置imageCache,然后扩展它的功能。 用我们自己的set # # # #替换ImageCache因为Flutter提供的ImageCache不能修改代码,所以我们直接复制ImageCache的源代码,继承ImageCache,然后用我们自己的set替换PaintingBinding的imageCache。 textimagemogr 2/auto-orientation/strip)如图:Flutter的PaintingBinding有一个公开createImageCache的方法。我们继承WidgetsFlutterBinding并重写该方法以返回我们自己的ImageCache。另外,在这里,我们还可以设置ImageCache的各种缓存大小。 扩展ImageCache # # # #的功能为了尽可能不修改ImageCache的代码,我们直接定义了一个新的缓存纹理的方法,对齐putIfAbsent方法的逻辑。核心代码逻辑如下:Alt text该方法主要参照putIfAbsent的逻辑实现。为了将纹理缓存到ImageCache中,做了以下关键扩展:TextureCacheKey是唯一识别纹理的关键,主要是根据宽度、高度和url来判断是否可以是同一纹理。 TextureImageStreamCompleter是纹理管理类,继承ImageStreamCompleter,内部保存纹理数据和成功下载的回调。 当缓存命中时,对象返回给应用层,从中获取纹理id,交给纹理Widget进行渲染。当缓存未命中时,会调用传入的loader方法构造TextureImageStreamCompleter,执行纹理的加载逻辑。 同时,将构造一个侦听器回调,并注册到TextureImageStreamCompleter中。 当纹理成功加载后,监听器方法将被回调。这个方法主要是计算纹理大小,放入缓存队列,检查缓存大小是否能超过最大值。如果有,之前使用时间最长的纹理会被淘汰。 这里要注意一点,普通图片是dart对象,Dart VM会自动回收。但是,我们的纹理对象的真实数据在引擎的共享内存中,所以我们需要手动管理纹理的释放。我们统计对纹理的引用,只有当没有widget持有纹理,引用计数为0时,才会真正释放。 同样,当上层纹理小部件dispose时,它也会调用下层ImageCache提供的接口,查看当前使用的纹理是否可以缓存或者正在使用。 只有没有的时候,质感效果才会真正释放出来。我们用搜索结果页面作为测试页面,里面包含了很多宝贝图片和各种重复的标签图片。 用华为荣耀20测试优化前后的物理内存使用情况。 操作步骤是:打开app,进入搜索结果页面,搜索同一个关键词,进入搜索结果页面,然后在10s的静默后滑过100条数据,最后停止操作。 物理内存每秒采样100s,得到如下数据:Alt文本蓝色曲线为优化前的内存占用,橙色曲线为优化后的内存占用。进入后可以看到占用的内存基本相同。 滑动时内存占用的减少是GC离场回收App的内存造成的。 总体来看,优化后占用的总内存比优化前少,GC带来的毛刺比优化前少。 期待上述方案,虽然在一个App中实现了内存缓存,存储了纹理和flutter图片,节省了内存空间,提高了内存利用率,但是仍然会侵入ImageCache的源代码,后续的Flutter引擎的更新和代码维护都需要额外的工作。 另外,由于在Flutter端加载原生图像,都是采取putIfAbsent的方法,而在Flutter端加载原始图像,这种情况在我们的app中时有发生,一张图像可能会占用数米内存,所以我们直接在putIfAbsent中加入大图像监控的方法。当加载的图像大小超过2M时,将会报告数据,包括图像的url、使用信息和大小。 这样我们就发现了几种图片使用不当的情况:直接使用Image.network加载原始图片,或者使用Image.asset加载大型本地资源。 作者:闲鱼科技-https://juejin.im/post/6888186410937106439参考链接:舒静关于我自己,我是一只帅气的安卓攻城狮,有6年的开发经验。记得喜欢就看,养成习惯。微信搜索“程修炼中心”关注这个喜欢写干货的程序员。 另外,历时两年整理收集的一线安卓厂面试完整测试现场PDF已经发布,资料【完整版】已经升级到我的【Github】。需要面试的朋友可以参考一下。如果对你有帮助,可以点一颗星!地址:[733 GH/樊雄]


  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【技术支持|常见问题】1556原创ng8文章搜索页面不齐(2024-05-01 14:43)
【技术支持|常见问题】1502企业站群-多域名跳转-多模板切换(2024-04-09 12:19)
【技术支持|常见问题】1126完美滑屏版视频只能显示10个(2024-03-29 13:37)
【技术支持|常见问题】响应式自适应代码(2024-03-24 14:23)
【技术支持|常见问题】1126完美滑屏版百度未授权使用地图api怎么办(2024-03-15 07:21)
【技术支持|常见问题】如何集成阿里通信短信接口(2024-02-19 21:48)
【技术支持|常见问题】算命网微信支付宝产品名称年份在哪修改?风水姻缘合婚配对_公司起名占卜八字算命算财运查吉凶源码(2024-01-07 12:27)
【域名/主机/服务器|】帝国CMS安装(2023-08-20 11:31)
【技术支持|常见问题】通过HTTPs测试Mozilla DNS {免费源码}(2022-11-04 10:37)
【技术支持|常见问题】别告诉我你没看过邰方这两则有思想的创意广告! (2022-11-04 10:37)

联系我们
Q Q:375457086
Q Q:526665408
电话:0755-84666665
微信:15999668636
联系客服
企业客服1 企业客服2 联系客服
86-755-84666665
手机版
手机版
扫一扫进手机版
返回顶部