-
避免內存泄露
內存泄露是造成OOM的最主要原因 常見的內存泄露: 1. 單例 因為單例是全生命周期的,如果引用了非全生命周期變量,就會導致內存泄露 2. 靜態(tài)變量 同樣也是生命周期長 3. Handler 因為非靜態(tài)內部類會持有外部類的引用,Activity destroy之后由于消息隊列還存在消息,handle對象無法被回收,就造成activity也無法銷毀;解決方案是使用靜態(tài)內部類創(chuàng)建handle,并在頁面退出的時候清空消息隊里 4. 資源使用完未關閉 比如BraodcastReceiver,ContentObserver io流 bitmap等等;解決方案就是及時關閉釋放 開發(fā)階段可以使用工具來實時監(jiān)測我們的程序是否有內存泄露:LwakCanary -
優(yōu)化圖片的內存占用
除了內存泄露,引發(fā)oom的第二大問題就是圖片的內存占用 1. bitmap 有時候我們需要直接對bitmap進行操作,可以基于軟引用自己實現(xiàn)一個bitmap緩存池,這樣對于同一個圖片,bitmap對象會重復使用(例如默認圖);這也是glide內部的做法;我們在使用context.getResources().getDrawable獲取圖片時,系統(tǒng)內部也維持了一個bitmap緩存池(由算法處理,一般是lru算法) 2. 圖片壓縮 在使用BitmapFactory解碼時,我們可以通過配置參數(shù)對待加載的圖片進行調整,一般有降低分辨率、改變加載模式(ARGB_8888==>RGB565)等 3. 在低級設備上加載更小的圖片,比如使用純色背景,使用更低分辨率的圖片 -
避免內存抖動
內存在頻繁的分配和回收時會造成gc頻繁工作,會導致卡頓,嚴重時會引發(fā)OOM 例如在循環(huán)中頻繁拼接String對象,會造成內存抖動;解決方案是采用StringBuffer和StringBuilder -
其它優(yōu)化
除了以上幾個比較大的情況會引發(fā)內存問題外,還有一些其它細節(jié)也會引發(fā)內存問題,需要有針對性的優(yōu)化 1. 數(shù)據(jù)結構優(yōu)化 在Android中使用SparseArrayMap和ArrayMap替代HashMAp 2. 避免使用枚舉 3. 列表復用(listview和recycleview) 4. 減少是視圖的層級 1. 使用constraintlayout替代線性布局和相對布局 2. 使用viewstub標簽延遲初始化視圖 5. 將一些復雜計算及占用內存的操作放到native層處理,比如音視頻解碼
工具
- LeakCanary監(jiān)測內存泄露
- MAT分析內存占用
- Android監(jiān)測內存實時情況,監(jiān)測內存抖動