轉自:Android系統(tǒng)Bitmap內存分配原理與優(yōu)化
一、前言
筆者最近致力于vivo游戲中心穩(wěn)定性維護,在分析線上異常時,發(fā)現有相當一部分是由OutOfMemory引起。談及OOM,我們一般都會想到內存泄漏,其實,往往還有另外一個因素——圖片,如果對圖片使用不當的話,很容易吃掉大量內存,從而導致異常。
尤其是游戲中心在2020末~2021初的幾個重要版本,上線了很多內容相關的feature,引入大量圖片、視頻列表,從而導致線上OOM占比上升。
在這篇文章中,筆者將講解一張看似普通的Bitmap對內存的占用,介紹Android Studio中幫助我們分析圖片占用內存的工具,舉例說明流行的兩大圖片加載框架:Glide、Picasso在加載圖片時使用內存的不同方式,接著分析不同drawable目錄下圖片的顯示策略,最后基于手機內存、版本,提出一種優(yōu)化內存分配的方案。
二、查看圖片內存占用
一張圖片在內存占用的空間究竟有多少,普遍存在的一個誤解是,圖片本身在磁盤上/從網絡下載下來是多大,就會占用多少的內存。這種說法是不正確的,圖片占用內存的大小不取決于它本身的大小,而取決于圖片庫所采用的展示方式所申請的內存。
拿鋼鐵俠這張圖片舉例,它的尺寸是350*350,可以看到在電腦磁盤上,它只占36KB的空間。

省略N多字。。。。。。。。
文章有點長,有興趣的去看原文,下面只轉載優(yōu)化的部分:
五、優(yōu)化策略
在實際的開發(fā)中,我們希望中高端機型加載更清晰的圖片(ARGB_8888),以提升用戶體驗,對于低端機型則希望加載占用內存更小的圖片(RGB_565),以降低OOM發(fā)生的概率??梢栽诔跏蓟疓lide時進行這樣的配置。需要留意的是不要對含透明區(qū)域的圖片采用這種優(yōu)化方案。
@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以節(jié)約內存
DecodeFormat.PREFER_RGB_565
} else {
DecodeFormat.PREFER_ARGB_8888
}
}
}
六、小結
借助一些開源工具,我們可以便捷地定位大圖,如滴滴開源的DoKit,篇幅原因不進行詳細介紹。最后,對于我們日常開發(fā)總結幾點建議,希望大家的應用穩(wěn)定性節(jié)節(jié)攀升。
在多圖的場景(比如RecyclerView)注意及時釋放圖片資源;
使用占據內存更小的圖片格式;
圖片源文件尺寸應當與目標ImageView相近;
優(yōu)先滿足xxhdpi、xxxhdpi的圖片資源需求;
根據設備性能,采用不同的圖片加載策略。