Android系统Bitmap内存分配原理与优化(转)

2023-07-26  本文已影响0人  不断学习

转自:Android系统Bitmap内存分配原理与优化

一、前言

笔者最近致力于vivo游戏中心稳定性维护,在分析线上异常时,发现有相当一部分是由OutOfMemory引起。谈及OOM,我们一般都会想到内存泄漏,其实,往往还有另外一个因素——图片,如果对图片使用不当的话,很容易吃掉大量内存,从而导致异常。

尤其是游戏中心在2020末~2021初的几个重要版本,上线了很多内容相关的feature,引入大量图片、视频列表,从而导致线上OOM占比上升。

在这篇文章中,笔者将讲解一张看似普通的Bitmap对内存的占用,介绍Android Studio中帮助我们分析图片占用内存的工具,举例说明流行的两大图片加载框架:Glide、Picasso在加载图片时使用内存的不同方式,接着分析不同drawable目录下图片的显示策略,最后基于手机内存、版本,提出一种优化内存分配的方案。

二、查看图片内存占用

一张图片在内存占用的空间究竟有多少,普遍存在的一个误解是,图片本身在磁盘上/从网络下载下来是多大,就会占用多少的内存。这种说法是不正确的,图片占用内存的大小不取决于它本身的大小,而取决于图片库所采用的展示方式所申请的内存。

拿钢铁侠这张图片举例,它的尺寸是350*350,可以看到在电脑磁盘上,它只占36KB的空间。


modb_20210701_4d88f4da-da01-11eb-b2db-38f9d3cd240d.png

省略N多字。。。。。。。。

文章有点长,有兴趣的去看原文,下面只转载优化的部分:

五、优化策略

在实际的开发中,我们希望中高端机型加载更清晰的图片(ARGB_8888),以提升用户体验,对于低端机型则希望加载占用内存更小的图片(RGB_565),以降低OOM发生的概率。可以在初始化Glide时进行这样的配置。需要留意的是不要对含透明区域的图片采用这种优化方案

@GlideModule

class MyGlideModule : AppGlideModule() {


    override fun applyOptions(context: Context, builder: GlideBuilder) {

        builder.setDefaultRequestOptions(RequestOptions().format(getBitmapQuality()))

    }



    private fun getBitmapQuality(): DecodeFormat {

        return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N || hasLowRam()) {

            // 低端机型采用RGB_565以节约内存

            DecodeFormat.PREFER_RGB_565

        } else {

            DecodeFormat.PREFER_ARGB_8888

        }

    }

}

六、小结

借助一些开源工具,我们可以便捷地定位大图,如滴滴开源的DoKit,篇幅原因不进行详细介绍。最后,对于我们日常开发总结几点建议,希望大家的应用稳定性节节攀升。

上一篇下一篇

猜你喜欢

热点阅读