Android性能優化:手把手帶你全面實現內存優化

示意圖

1. 定義

優化處理 應用程序的內存使用、空間佔用java


2. 做用

避免因不正確使用內存 & 缺少管理,從而出現 內存泄露(ML)、內存溢出(OOM)、內存空間佔用過大 等問題,最終致使應用程序崩潰(Crashandroid


3. 儲備知識:Android 內存管理機制

3.1 簡介

下面,將針對回收 進程、對象 、變量的內存分配 & 回收進行詳細講解git

3.2 針對進程的內存策略

a. 內存分配策略

ActivityManagerService 集中管理 全部進程的內存分配github

b. 內存回收策略

  • 步驟1:Application Framework 決定回收的進程類型
    Android中的進程 是託管的;當進程空間緊張時,會 按進程優先級低->>高的順序 自動回收進程

Android將進程分爲5個優先等級,具體以下:算法

  • 步驟2:Linux 內核真正回收具體進程
    1. ActivityManagerService 對 全部進程進行評分(評分存放在變量adj中)
    2. 更新評分到Linux 內核
    3. Linux 內核完成真正的內存回收

此處僅總結流程,這其中的過程複雜,有興趣的讀者可研究系統源碼ActivityManagerService.java緩存

3.3 針對對象、變量的內存策略

  • Android的對於對象、變量的內存策略同 Java
  • 內存管理 = 對象 / 變量的內存分配 + 內存釋放

下面,將詳細講解內存分配 & 內存釋放策略性能優化

a. 內存分配策略

  • 對象 / 變量的內存分配 由程序自動 負責
  • 共有3種:靜態分配、棧式分配、 & 堆式分配,分別面向靜態變量、局部變量 & 對象實例
  • 具體介紹以下

注:用1個實例講解 內存分配微信

public class Sample {    
    // 該類的實例對象的成員變量s一、mSample1 & 指向對象存放在堆內存中
    int s1 = 0;
    Sample mSample1 = new Sample();   
    
    // 方法中的局部變量s二、mSample2存放在 棧內存
    // 變量mSample2所指向的對象實例存放在 堆內存
    public void method() {        
        int s2 = 0;
        Sample mSample2 = new Sample();
    }
}
    // 變量mSample3的引用存放在棧內存中
    // 變量mSample3所指向的對象實例存放在堆內存
    // 該實例的成員變量s一、mSample1也存放在堆內存中
    Sample mSample3 = new Sample();

b. 內存釋放策略

  • 對象 / 變量的內存釋放 由Java垃圾回收器(GC) / 幀棧 負責
  • 此處主要講解對象分配(即堆式分配)的內存釋放策略 = Java垃圾回收器(GC

因爲靜態分配不需釋放、棧式分配僅 經過幀棧自動出、入棧,較簡單,故不詳細描述數據結構

  • Java垃圾回收器(GC)的內存釋放 = 垃圾回收算法,主要包括:
 
垃圾收集算法類型
  • 具體介紹以下
 
總結

4. 常見的內存問題 & 優化方案

  • 常見的內存問題以下app

    1. 內存泄露
    2. 內存抖動
    3. 圖片Bitmap相關
    4. 代碼質量 & 數量
    5. 平常不正確使用
  • 下面,我將詳細分析每項的內存問題 & 給出優化方案

4.1 內存泄露

  • 簡介
    ML (Memory Leak),指 程序在申請內存後,當該內存不需再使用 但 卻沒法被釋放 & 歸還給 程序的現象

  • 對應用程序的影響
    容易使得應用程序發生內存溢出,即 OOM

內存溢出 簡介:

  • 發生內存泄露的本質緣由

4.2 圖片資源Bitmap相關

  • 優化緣由
    即 爲何要優化圖片Bitmap資源,具體以下圖:

     

  • 優化方向
    主要 從 如下方面優化圖片Bitmap資源的使用 & 內存管理

     

  • 具體優化方案
    下面,我將詳細講解每一個優化方向的具體優化方案

關於更加具體的介紹,請看文章:Android性能優化:那些關於Bitmap優化的小事

4.3 內存抖動

  • 簡介

     
  • 優化方案
    儘可能避免頻繁建立大量、臨時的小對象


4.4 代碼質量 & 數量

  • 優化緣由
    代碼自己的質量(如 數據結構、數據類型等) & 數量(代碼量的大小)可能會致使大量的內存問題,如佔用內存大、內存利用率低等

  • 優化方案
    主要從代碼總量、數據結構、數據類型、 & 數據對象引用 方面優化,具體以下


4.5 常見使用

  • 優化緣由
    一些常見使用也可能引起大量的內存問題,下面我將詳細介紹。

  • 優化方案

注:

  1. 還有1個內存優化的終極方案:調大 虛擬機Dalvik的堆內存大小
  2. 即 在AndroidManifest.xmlapplication標籤中增長一個android:largeHeap屬性(值 = true),從而通知虛擬機 應用程序需更大的堆內存
  3. 但不建議 & 不鼓勵該作法

4.6 額外小技巧

此處,還有一些內存優化的小技巧但願告訴給你們

  • 技巧1:獲取當前可以使用的內存大小
    調用 ActivityManager.getMemoryClass()方法可獲取當前應用可用的內存大小(單位 = 兆)

  • 技巧2:獲取當前的內存使用狀況
    在應用生命週期的任何階段,調用 onTrimMemory()獲取應用程序 當前內存使用狀況(之內存級別進行識別),可根據該方法返回的內存緊張級別參數 來釋放內存

Android 4.0 後提供的一個API

  • 技巧3:當視圖變爲隱藏狀態時,則釋放內存
    當用戶跳轉到不一樣的應用 & 視圖再也不顯示時, 應釋放應用視圖所佔的資源
  1. 注:此時釋放所佔用的資源能顯著的提升系統的緩存處理容量
  2. 具體操做:實現當前Activity類的onTrimMemory()後,當用戶離開視圖時會獲得通知;若獲得返回的參數 = TRIM_MEMORY_UI_HIDDEN 即表明視圖變爲隱藏狀態,則可釋放視圖所佔用的資源.

5. 輔助內存優化的分析工具

  • 哪怕徹底瞭解 內存的緣由,但不免仍是會出現人爲難以發現的內存問題
  • 下面將簡單介紹幾個主流的輔助分析內存優化的工具,分別是
    1. MAT(Memory Analysis Tools)
    2. Heap Viewer
    3. Allocation Tracker
    4. Android Studio 的 Memory Monitor
    5. LeakCanary

5.1 MAT(Memory Analysis Tools)

  • 定義:一個EclipseJava Heap 內存分析工具 ->>下載地址
  • 做用:查看當前內存佔用狀況

經過分析 Java 進程的內存快照 HPROF 分析,快速計算出在內存中對象佔用的大小,查看哪些對象不能被垃圾收集器回收 & 可經過視圖直觀地查看可能形成這種結果的對象

5.2 Heap Viewer

  • 定義:一個的 Java Heap 內存分析工具
  • 做用:查看當前內存快照

可查看 分別有哪些類型的數據在堆內存總 & 各類類型數據的佔比狀況

5.3 Allocation Tracker

5.4 Memory Monitor

5.5 LeakCanary

至此,關於內存優化的全部知識講解完畢


6. 總結

  • 本文主要講解內存優化的相關知識,總結以下:
做者:Carson_Ho 連接:https://www.jianshu.com/p/9745a9375191 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。
相關文章
相關標籤/搜索