Bitmap進化史及不同版本下的回收

在App開發中,如果對Bitmap的管理不是很謹慎,就很容易出現OOM。雖然現在網上有許多優秀的開源圖片加載框架,但在有些情況無法使用那些框架去加載圖片,比如比較 複雜的自定義View。本文結合GOOGLE的一篇文章(原文地址)對不同版本Bitmap的變化以及如何更好地回收掉做下介紹,如果有不對的地方,歡迎指正。


Android管理Bitmap內存進化史

在Android2.2(API8)及更早版本,當GC(Garbage collection)觸發,你的app線程停止,這將導致可以降低性能的滯後

在Android2.3(API9)添加併發GC,也就是說,當一個bitmap對象不再被引用,gc將盡快的回收掉bitmap使用的內存

在Android2.3.3(API10)及更早版本,一個bitmap對象所包含的像素數據是存在本地內存(native memory,也就是 Dalvikheap)當中,也就是說像素數據與bitmap本身是分離開來的,而在native memory中的像素數據不會按預期的方式釋放掉,這也就有可能導致程序超過內存的限制並OOM

在Android3.0(Api11)及之後版本,像素數據與關聯的bitmap都保存在Dalvik heap中


在不同版本管理Bitmap 內存

在Android2.3.3(API10)及之前版本,google推薦使用recycle()方法來釋放內存,recycle()會盡快的去釋放掉bitmap使用的內存,注意,如果你確定不再使用這個bitmap的時候再調用recycle()方法,如果調用以後再次使用這個bitmap,將會產生錯誤"Canvas:trying to use a recycled bitmap"

在Android3.0(API11)及之後版本,android引入了BitmapFactory.Options.inBitmap屬性,如果設置了這個屬性,使用decode方法去獲取bitmap時,android將會嘗試重用一個已經存在的bitmap並替換像素數據,也就是說bitmap的內存被重用了,這樣做的好處是省去了申請內存以及將之前申請的內存釋放掉的過程,也就提升了應用的性能。但是,使用inBitmap有嚴格的限制,在android4.4(API19)之前,只有同樣大小的bitmap才支持此屬性,就是說,如果已經存在一個不需要的bitmap大小爲400*400,而你此時要加載一個400*400的bitmap,則可以將新的bitmap的像素數據填充到之前的bitmap中,這樣不必再釋放之前的bitmap內存,然後再爲新的bitmap重新申請內存,但是如果新要加載的bitmap大小與之前的bitmap尺寸不一,則無法複用。如果decode無法使用這個bitmap,decode方法將會返回null並拋出IllegalArgumentException,感覺還是挺麻煩的,具體使用可以參考官方API。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章