內存泄漏改進方案及代碼修改

1. 內存泄漏類型html

本次內存優化,發現以下內存泄漏類型:java

  • Bitmap未即時釋放緩存

  • Handler泄漏ide

  • static成員泄漏優化

  • Callback泄漏spa

  • Activity leak window設計

  • cursor未關閉htm

內存泄漏問題詳細描述,參見《內存優化評估文檔》對象

下面將描述不一樣內存泄漏類型的解決方案。blog

 

2. 內存泄漏解決方案

2.1 Bitmap未即時釋放

2.1.1泄漏緣由

業務代碼沒有及時主動釋放Bitmap,容易形成短期內內存被大量佔用,進一步誘發OOM的發生。

2.1.2解決方案

        解決方案思路有兩種狀況:

   1) 對於從文件系統加載、Drawable資源加載,創建二級緩存管理該類Btimap;

 2) 對於內存建立、圖形變換產生的Bitmap,由業務本身去即時釋放資源。

     ImageUtisBitmapUtils封裝了Bitmap加載/獲取的二級緩存機制,加載文件系統的Bitmap,推薦使用ImageUtils中的getBitmap系列方法。

2.1.3實例

  • 調用ImageUtis獲取Bitmap

1描述了使用二級緩存管理Bitmap

 

1使用二級緩存管理Bitmap

  • 自行管理Bitmap

2描述了自行管理Bitmap釋放。

2自行管理Bitmap釋放

2.2 Handler泄漏

2.2.1泄漏緣由

Handler泄漏的緣由,大可能是匿名構建Handler實例,從而持有外部類Activity實例致使。

2.2.2解決方案

       解決方案思路有兩種:

1)去除Handler實例持有的外部類引用,該類思路的作法,通常是將Handler的子類定義爲靜態內部類,或者以一個單獨的類文件形式存在;

2)保證在Activity/Service退出時,清空消息隊列中與Handler有關的全部消息。

      推薦使用第一種思路,實現起來簡單、高效,第二種思路雖也可實現,但要考慮的面比較多,容易產生遺漏。

2.2.3實例

3描述了MyCellLayout.java文件中,有一個Handler泄漏實例。

3 Handler泄漏實例

4中所示代碼對圖3中的Handler泄漏作了修復。

4 3 Handler泄漏修復

2.3 static成員泄漏

2.3.1泄漏緣由

Static類成員,其生命週期與App生命週期近乎等長,在不合理的設計中,static類成員持有的對象,其內部持有Activity實例等致使。

2.3.2解決方案

      解決方案思路有兩種:

5)在static類成員持有的對象內部, 規避持有Activity實例;

6)避免使用static成員。

2.3.3實例

      圖5描述了 GlobalMsgProcessHelper.javastatic類成員泄漏。

5 static類成員泄漏

      圖6是對圖5 static類成員泄漏的修復。

6 5 static類成員泄漏修復

2.3 Callback泄漏

2.4.1泄漏緣由

Callback直接或間接持有Activity實例等致使。

2.4.2解決方案

解決方案思路,在Callback對象內部規避持有Activity實例。

2.4.3實例

      參見DeviceCategoryView.java DeviceCategoryDownloadCallback


2.5 Activity leak window

2.5.1泄漏緣由

Activity異外先於Dialog退出,致使本異常拋出,本質也是一種內存泄漏。

2.5.2解決方案

構建BaseDialog,使全部自定義Dialog均擴展自此類,在BaseDialog內部實如今Activity退出前先行銷燬的邏輯。

2.5.3實例

      圖7 描述了BaseDialog實現自釋放邏輯。

      圖8 描述了CommonDialog派生自BaseDialog

7 BaseDialog實現自釋放邏輯

8 CommonDialog派生自BaseDialog

2.6 cursor未關閉

2.6.1泄漏緣由

Cursor使用完後等致使。

2.6.2解決方案

解決方案思路,在Cursor使用完後釋放資源。

2.6.3實例

      圖9描述了Cursor泄漏修復。

9 Cursor泄漏修復

相關文章
相關標籤/搜索