簡述Android OOM

什么是OOM

? ? ? 移動端內存有限,手機給每個應用分配大小有限(Google 源生OS分配的內存為16M或者24M,但是不同廠家的ROM會修改)。當你使用的內存空間接近閥值,實例化新對象,需要分配新的內存空間是。就會報Out of Memory。

產生OOM的主要情況

1.同時加載大量大內存對象。主要體現在加載大量Bitmap(如幀動畫、RecyclerView),內存一下沖破閥值,產生OOM。

2.內存泄露。內存泄漏(Memory Leak)是指程序中己動態分配的堆內存由于某種原因程序未釋放或無法釋放,造成系統內存的浪費,導致程序運行速度減慢甚至系統崩潰等嚴重后果。當內存泄露到一定的量,接近閥值的時候,再去new新對象時就會OOM。

OOM的監測

查找內存泄漏可以使用Android Studio 自帶的Android Profiler工具(Android Studio3.0之后不僅可以監測內存,還可以監測CPU和network),也可以使用Square產品的LeadCanary(帖一個使用說明地址http://www.lxweimin.com/p/7db231163168)。

ps:看過一個面試問題。OOM能不能try/catch ? try/catch可以避免這次報錯,但是沒有真正處理內存問題,還是可能再下一分配內存的位置觸發。

OOM的解決方式

加載大量圖片

? 1. Bitmap壓縮。BitmapFactory,可以修改質量。比如把ARGB.8888改成RGB.565,bitmap占用內存會縮小一半(但是去掉了透明度,有些圖片沒法直接轉。Glide就默認設置的是RGB.565)。Options.inSampleSize可以壓縮圖片比例。

? 2. 緩存。LruCache是常用的第三方框架的圖片緩存處理方式。LruCache使用一個LinkedHashMap簡單的實現內存的緩存,沒有軟引用,都是強引用。如果添加的數據大于設置的最大值,就刪除最先緩存的數據來調整內存。

? 3. 軟引用&弱引用。當一個對象只有軟引用的時候,如果內存不足就會回收。當一個對象只有弱引用的時候,不管當前內存空間足夠與否,都會回收它的內存。不過,由于垃圾回收器是一個優先級很低的線程, 因此不一定會很快發現那些只具有弱引用的對象。

? 4.替換.png圖片。用較小的圖片替換.png,比如jpg或者svg等。

內存泄露

? ? 1.靜態變量導致內存泄露。如一個靜態變量持有當前Activity對象(但是很少有人會這么干吧)。

? ? 2.單例模式導致的內存泄露。單例模式的特點是它的生命周期與Application一致。所以單例模式實例化對象時,要用Application.context。

? ? 3.非靜態內部類和匿名內部類導致的內存泄露。非靜態內部類和匿名內部類隱式持有外部類的引用。Handler經常會不注意的時候寫成匿名內部類,就造成內存泄露。

? ? 4.資源未關閉導致的內存泄露。資源性對象比如Cursor,Stream、File文件等往往都用了一些緩沖,不使用的時候,應該及時關閉它們,否則會造成內存泄漏。

? ? 5.屬性動畫導致的內存泄露。屬性動畫中的無限循環動畫,如果沒有在onDestroy中停止,盡管界面上看不到動畫效果,但是Activity還是被View持有,會導致內存泄露。

? ? 6.集合容器導致內存泄露。當不需要對象時,并沒有把它的引用從集合中清理掉,也是一種內存泄露。

一些相關的細節

? ? 1.StringBuffer、StringBuilder和String一樣,也用來代表字符串。String類是不可變類,任何對String的改變都會引發新的String對象的生成;StringBuffer、StringBuilder則是可變類,任何對它所指代的字符串的改變都不會產生新的對象。StringBuffer考慮了線程安全,StringBuilder沒有。但是單線程StringBuilder效率更高。

? ? 2.內存抖動是由于短時間內有大量對象進出新生代區導致的,它伴隨著頻繁的GC。如在view的OnDraw方法中實例化對象,或者在循環中實例化不必要的對象。內存抖動可能會導致UI線程被頻繁阻塞,畫面卡頓。

總結

? ? OOM是同時加載大量大內存圖片或者gc無法及時回收對象,達到內存閥值之后的報錯。需要通過寫代碼時注意和后期監測來避免。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,287評論 25 708
  • HereAndroid的內存優化是性能優化中很重要的一部分,而避免OOM又是內存優化中比較核心的一點。這是一篇關于...
    HarryXR閱讀 3,849評論 1 24
  • 本文轉載來源 http://www.csdn.net/article/2015-09-18/2825737/1 (...
    yoosir閱讀 1,136評論 0 5
  • 又到情人節,這每一年的2.14號都是情侶們撒狗糧的日子,除了鮮花禮物,朋友圈里曬得最多的就是美食了。吃,不再是生活...
    vicky寶兒閱讀 475評論 0 0
  • 剛參加完第八屆走親戚,無疑是校外美術的一次盛典,對于一個剛起步的小畫室或者年輕的教師本身來說都是一次學習開拓視野的...
    蝴蝶畫閱讀 203評論 1 0