OOM out of memory(內(nèi)存溢出)
最近做一個項目的時候杖玲,將測試切換到有大量數(shù)據(jù)的環(huán)境下,程序出現(xiàn)了OOM寄症。在不懈努力下序愚,終于在上線之前解決這個問題憔披。
Android內(nèi)存
Android系統(tǒng)的dalvik虛擬機會為每個應(yīng)用程序分配堆內(nèi)存,分配的堆內(nèi)存的大小由機器的內(nèi)存大小決定(這點和ios不一樣爸吮,ios程序的應(yīng)用內(nèi)存幾乎可以使用ios設(shè)備的整個內(nèi)存空間芬膝,ios開發(fā)者幾乎很少遇到OOM)。當(dāng)你的程序需要一塊新的內(nèi)存時形娇,系統(tǒng)會去申請Java空間锰霜,如果你申請的空間超過閾值,系統(tǒng)就會拋出OOM桐早。
OOM原因
當(dāng)你銷毀一個對象的時候癣缅,系統(tǒng)會自動GC,釋放資源勘畔,所以出現(xiàn)OOM無非就是以下兩個原因:
(1)對象過大所灸,系統(tǒng)無法分配資源,例如bitmap炫七,file等大對象。
(2)GC問題钾唬,資源無法回收万哪。例如static變量,context對象抡秆,handler對象
OOM主要問題與解決辦法
問題1:加載大量圖片時奕巍,OOM
這是OOM比較常見的問題,可以從以下方面優(yōu)化:
(1)采用成熟的三方控件儒士,如glide的止,fresco
(2)壓縮圖片,修改圖片Bitmap.Config 為565
(3)如果允許着撩,可以在手動清理內(nèi)存中的圖片緩存诅福,如果是用的是列表匾委,不建議這樣處理,會導(dǎo)致列表往回滑時圖片重新加載氓润,消耗大量網(wǎng)絡(luò)資源赂乐。
問題2:context資源無法釋放
? ? ? ?在Android開發(fā)中,必然會用到大量的context資源咖气,但是有些時候挨措,比如你寫了一個靜態(tài)的公共方法,你傳了一個activity的context進去崩溪,然后你退出了這個activity浅役,你以為你這個activity已經(jīng)回收,但是并沒有伶唯。
? ? ?activity是有生命周期的觉既,如果你的activity中的成員對象的生命周期超過了activity的生命周期,就會造成在activity銷毀的時候抵怎,你的成員對象無法銷毀奋救。所以在使用context的地方,盡量使用application的context反惕,application的生命周期貫穿整個程序尝艘,這樣你的activity銷毀后就不會存在于內(nèi)存中了。
問題3:handler無法GC
? ? ? 當(dāng)結(jié)束activity時姿染,如果handler在主線程中背亥,消息還在隊列中沒有處理,那么GC無法回收handler對象悬赏,也無法回收承載這個handler對象的activity狡汉。
? ? ? 使用靜態(tài)內(nèi)部類可以解決這個問題,使用activity的弱引用:
解決辦法可以參照stack overflow:Handlers and memory leaks in Android - Stack Overflow
第一次寫博客闽颇,寫的不詳細盾戴,請大家多多指教,后面我寫寫我是如何運用AS分析和優(yōu)化內(nèi)存