1. ANR異常(Application Not Responsing:應用程序無響應的彈框)
(1) 原因:在主線程進行了耗時操作(如:網(wǎng)絡IO操作、數(shù)據(jù)庫操作或耗時計算等)
拓展:運行在主線程的操作如下每窖,盡量避免在它們里面進行耗時操作睡陪。
- Activity:Activity的所有生命周期回調運行在主線程(當然可在Activity生命周期回調中開啟子線程執(zhí)行耗時操作)
- service:service運行在主線程(當然可在Service中開啟子線程執(zhí)行耗時操作盖矫,如封裝好的IntentService內有一個工作線程用來處理耗時操作)
- Broadcast:BroadcastReceiver的onReceive()回調運行在主線程
- Handler:主線程中l(wèi)ooper的Handler對象的handMessage()和post(runnable)方法運行在主線程
- AsyncTask:AsyncTask回調中除了doInBackground()方法种柑,其他回調(UI更新相關)都運行在主線程
(2) 解決ANR:主線程中避免耗時操作,讓子線程執(zhí)行耗時任務
定欧∮婧牵可參考異步消息處理機制
- Thread:創(chuàng)建子線程執(zhí)行耗時操作
- AsyncTask:抽象類AsyncTask派生出子類的doInBackground()方法來中執(zhí)行耗時操作
- HandlerThread:HandlerThread線程中創(chuàng)建Handler對象,在handleMessage()方法中執(zhí)行耗時操作
- IntentService:重寫IntentService的onHandleIntent()方法執(zhí)行耗時任務
2. OOM異常(Out Of Memory)
2.1 概念區(qū)分
- 內存抖動:短時間內大量對象被創(chuàng)建又馬上被GC釋放砍鸠,即頻繁GC(垃圾回收)扩氢。瞬間產生的對象會嚴重占用內存區(qū)域,內存區(qū)域達到閥值時會觸發(fā)GC回收掉不用的對象爷辱,導致剛剛產生的對象又被回收录豺。
- 內存泄漏:進程中的某些對象已經沒有被其他地方引用,但是他們卻可以直接或間接地引用其他沒被回收的對象饭弓,導致GC無法產生作用巩检。
- 內存溢出(OOM):android系統(tǒng)會給每個安卓程序分配一定的內存,當程序所使用的內存超過最大值就會造成內存溢出示启,就是常說的OOM。
有些內存沒有被釋放從而失去控制领舰,造成程序可使用的內存越來越少夫嗓,系統(tǒng)運行速度減慢迟螺,嚴重情況下會導致程序崩潰,所以內存溢出是最嚴重的內存問題舍咖,必須解決矩父。
備注
:內存抖動或內存泄漏累積到一定程度都會造成內存溢出。
2.2 OOM原因
原因:當前占用的內存 + 我們申請的內存資源 > Dalvik虛擬機被分配的最大內存排霉,常見于Bitmap大圖加載時出現(xiàn)OOM窍株。
備注:android系統(tǒng)會為每個應用程序分配一個獨立的工作空間(即Dalvik虛擬機空間),使各個app運行互不影響攻柠;android系統(tǒng)為每一個Dalvik虛擬機設定了最大內存限制球订。
2.3 解決OOM
(1) Bitmap造成的OOM解決(Bitmap優(yōu)化)
- 大圖壓縮:根據(jù)壓縮比(計算inBitmap屬性值)獲取縮略圖
- 圖片顯示:加載4類圖片資源
- 及時釋放Bitmap內存:通過recycle()回調方法回收資源
- 捕獲異常(Error屬性可以捕獲到OOM,Exception屬性捕獲不到)
(2) 其他OOM解決
- ListView(convertView復用 + 圖片三級緩存機制LRU)
- 避免在onDraw()方法里執(zhí)行對象的創(chuàng)建(頻繁GC瑰钮,造成內存抖動冒滩,積累到一定程度導致內存溢出)
- 謹慎使用多進程(使用復雜,同時使用不當會造成更多的內存溢出和程序錯誤浪谴,盡量不要使用)
3. Bitmap位圖
4. UI卡頓
(1) UI卡頓原理
android系統(tǒng)每隔16ms就會觸發(fā)一次頁面渲染开睡,若渲染成功(16內能完成相關計算),就更夠達到每秒60幀(60fps)的流暢效果苟耻;若渲染不成功(16內不能完成相關計算:耗時操作篇恒、布局復雜、動畫等原因)凶杖,就會丟幀造成UI卡頓胁艰。
1秒渲染次數(shù) = 1s/16ms =1000ms/16ms = 62.5次頁面渲染。
(2) UI卡頓常見原因
UI卡頓原因 | 分析 | 優(yōu)化 | 備注 |
---|---|---|---|
UI線程做了輕微的耗時操作
|
嚴重將導致ANR | 開啟子線程做耗時操作 | 異步消息處理框架 |
布局 layout過于復雜 |
無法在16ms內完成渲染 | 布局優(yōu)化 | - |
布局層疊 | 導致View過渡繪制(某些像素在同一幀時間內被繪制多次) | 布局優(yōu)化 | View頻繁地觸發(fā)measure(測量)和layout(擺放)方法官卡,導致耗時過多及整個View頻繁地重新渲染蝗茁,從而使CPU或GPU負載過重 |
同一時間動畫 執(zhí)行次數(shù)過多 |
導致CPU或GPU負載過重 | 合理地使用動畫 | 動畫雖效果好,但是更易造成性能要求 |
內存頻繁觸發(fā)GC(垃圾回收) | 導致暫時阻塞渲染操作 | - | - |
代碼質量 | 冗余資源及邏輯等導致加載和執(zhí)行緩慢 | 代碼優(yōu)化 | - |
5. 內存泄漏
6. 內存管理
(1) 內存管理 = 內存分配 + 內存回收
(2) android 進程優(yōu)先級:前臺進程 > 可見進程 > 服務進程 > 后臺進程 > 空
備注:系統(tǒng)會先回收優(yōu)先級低的進程寻咒。
7. 冷啟動優(yōu)化
8. 其他優(yōu)化
(1) 盡量不要用靜態(tài)變量存儲核心數(shù)據(jù)
(2) 有關sharePreference的安全問題
- 不能跨進程讀寫
- 不能存儲大數(shù)據(jù):sharePreference以key\value的形式存儲存儲數(shù)據(jù)哮翘,存儲過大數(shù)據(jù)易阻塞主線程,造成UI卡頓
(3) 內存對象序列化
(4) 避免在UI線程做繁重操作