零零碎碎的東西老是記不長久,僅僅學習別人的文章也只是他人咀嚼後留下的殘渣。無心中發現了這個每日一道面試題,想了想若是隻是簡單地去思考,那麼不只會收效甚微,甚至難一點的題目本身可能都懶得去想,堅持不下來。因此不如把每一次的思考、理解以及別人的看法記錄下來。不只加深本身的理解,更要激勵本身堅持下去。git
什麼是OOM
「OOM」也就是「out of memory」,意思是內存用完了。也就是說,當你去申請內存的時候,你須要的內存過大,app剩下的空餘內存已經不夠你使用,若是你沒有捕獲這個異常,系統就沒辦法了,會直接崩潰並拋出OOM異常。github
系統分配給每個app運行的內存空間是有限的,因此做爲一名Android開發者,咱們必定要謹慎當心的使用內存。面試
OOM的類型
首先OOM的緣由就是app進程可用內存不足,有兩種狀況緩存
- 內存申請的速度大於gc釋放內存的速度
- 內存出現泄漏,gc沒法回收泄露的內存,致使可用內存愈來愈少
第一種狀況又會有兩種不一樣的類型app
- 一次性須要的內存過大,可用內存不足。常見的是使用圖片資源時加載爲bitmap存儲到內存,圖片分辨率越高,須要的內存就越大,就可能形成OOM。
- 頻繁的建立內存佔用小的對象,致使內存碎片,這種叫內存抖動。雖然總體上還有內存可分配,可是這些內存空間並不連續,沒法知足需求,致使OOM。常見的有ListView中contentView的建立、頻繁使用String進行字符串的拼接、onDraw方法裏對象的頻繁建立。這一類問題要解決基本的方法就是複用已建立的對象
第二種狀況就是內存泄漏,內存泄漏與OOM的關係就是量變到質變的過程,內存泄漏一定會致使可用內存的減小,大量的內存泄漏就會致使OOM問題。關於內存泄漏的具體例子在第3期已經很詳細的探討過,這裏就再也不贅述。佈局
OOM的預防
這裏總結幾點,無非是兩個方面:post
- 提升系統分配的可用內存。假如app確實須要很大的內存空間,那麼能夠再manifest文件中設置
largeHeap="true"
增長內存的的申請量
- 減小app的內存使用
- ImageView使用合適的尺寸,多圖顯示縮略圖,點擊查看大圖
- ListView使用ViewHolder複用contentView。不過如今大都用RecycleView,強制配合ViewHolder使用
- 減小bitmap對象內存的佔用,可用Lru緩存、三級緩存、合適的編碼等
- onDraw等頻繁調用的方法中避免建立對象
- 優化佈局,少用LinerLayout多用RelativeLayout
- 字符串拼接問題儘可能使用StringBuilder而不是String的+
在內存泄漏方面學習
- 使用靜態內部類
- 靜態類引用使用Application的Context而不是Activity的Context
- 相似廣播、監聽器等記得取消註冊
- 遊標、文件等資源使用完畢必定要關閉
- 靜態集合使用完畢記得清空
- 根據不一樣場景,善用軟引用、弱引用