每日一道面試題(第5期)---哪些狀況下會致使OOM問題

零零碎碎的東西老是記不長久,僅僅學習別人的文章也只是他人咀嚼後留下的殘渣。無心中發現了這個每日一道面試題,想了想若是隻是簡單地去思考,那麼不只會收效甚微,甚至難一點的題目本身可能都懶得去想,堅持不下來。因此不如把每一次的思考、理解以及別人的看法記錄下來。不只加深本身的理解,更要激勵本身堅持下去。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
  • 相似廣播、監聽器等記得取消註冊
  • 遊標、文件等資源使用完畢必定要關閉
  • 靜態集合使用完畢記得清空
  • 根據不一樣場景,善用軟引用、弱引用
相關文章
相關標籤/搜索