Android性能優化篇之內存優化--內存優化分析工具

image

引言

1. Android性能優化篇之內存優化--內存泄漏

2.Android性能優化篇之內存優化--內存優化分析工具

3.Android性能優化篇之UI渲染性能優化

4.Android性能優化篇之計算性能優化

5.Android性能優化篇之電量優化(1)——電量消耗分析

6.Android性能優化篇之電量優化(2)

7.Android性能優化篇之網絡優化

8.Android性能優化篇之Bitmap優化

9.Android性能優化篇之圖片壓縮優化

10.Android性能優化篇之多線程并發優化

11.Android性能優化篇之數據傳輸效率優化

12.Android性能優化篇之程序啟動時間性能優化

13.Android性能優化篇之安裝包性能優化

14.Android性能優化篇之服務優化

介紹

上一章講了內存相關的知識和內存泄漏的常見案例以及解決方法,我們寫代碼的時候要注意避免。但是我們不可能完全避免出現內存泄漏的情況,所以就要通過內存分析工具來分析是否產生了內存泄漏。主要講的工具有以下幾種:

Heap Snapshot
Heap Viewer
MAT
Allaction Tracking
TraceView
LeakCanary
Lint


下面我們就來一一講解這些工具的使用:

1.Heap Snapshot

Heap Snapshot 是 android Studio 中 Android Monitor中的一個分析Java堆內存信息的工具,這邊我們就用上章中的單例導致內存泄漏的例子來分析:

(1).Heap Dump啟動

點擊圖中紅色框中的Dump Java Heap,就會dump 出java堆內存信息文件(.hprof)


image1.png
(2).分析Heap Snapshot面板中的信息

android studio會自動打開hprof文件,我們這時候就可以來重點分析我們需要檢查的類是否有內存泄漏(必須要確定分析具體的類,比如我們分析MainActivity是否有內存泄漏,可以反復的改變屏幕的方向,然后dump出堆信息)


image2.png

我們看到ClassName中可能數據太多,我們怎么能夠定位到我們要分析的類呢,可以選擇第二個紅色框中的選擇項來快的定位。


image4.png

我們選擇通過包來展示,這樣可以通過包名來快速定位。
image5.png

下面我們來分析下MainActivity是否有內存泄漏。


image6.png

我們看到這里MainActivity有兩個實例且都有深度,也就是說都被引用,根據Acitivity的生命周期原理,屏幕的旋轉會回收之前的Activity,然后創建一個新的Activity,另一個一個被回收或者等待被回收,所以MainActivity肯定存在內存泄漏的問題。這個需要結合下面的引用樹來看,但是這個太麻煩還不要用對,下面我們將介紹更好的工具來分析,這邊只要知道我們分析的類是否發生內存泄漏就行了。


下面我們給出Snapshot中表中字段含意:

Class Name 板塊
    Total Count     內存中該類的對象個數
    Heap Count      堆內存中該類的對象個數
    Sizeof          物理大小
    Shallow size    該對象本身占有內存大小
    Retained Size   釋放該對象后,節省的內存大小

Instance 板塊

    depth           深度
    Shallow Size    對象本身內存大小
    Dominating Size 管轄的內存大小


2.Heap Viewer

Heap Viewer 是 Android Device Monitor 中的實時查看App分配的內存大小和空閑內存大小和發現內存泄漏的工具。
使用條件:1.必須5.0以及以上的系統,2.開發者選項可用

使用步驟:
    1.打開Android Device Monitor 
    2.點擊DDMS
    3.選中heap選項卡
    4.選中我們的項目
    5.點擊update heap
    6.點擊Cause GC
image7.png
下面解釋下Heap面板中表示的意思:
image8.png

A

    Heap Size   堆棧分配給App的內存大小
    Allocated   已分配使用的內存大小
    Free    空閑的內存大小
    %Used   Allocated/Heap Size,使用率
    Objects 對象數量

B 中 Type 類型

    free    空閑的對象
    data object 數據對象,類類型對象,最主要的觀察對象
    class object    類類型的引用對象
    1-byte array(byte[],boolean[])  一個字節的數組對象
    2-byte array(short[],char[])    兩個字節的數組對象
    4-byte array(long[],double[])   4個字節的數組對象
    non-Java object 非Java對象

B 中 表中列的表示意思

    Count   數量
    Total Size  總共占用的內存大小
    Smallest    將對象占用內存的大小從小往大排,排在第一個的對象占用內存大小
    Largest 將對象占用內存的大小從小往大排,排在最后一個的對象占用的內存大小
    Median  將對象占用內存的大小從小往大排,拍在中間的對象占用的內存大小
    Average 平均值

當我們點擊某一行時,可以看到 C 的柱狀圖 ,表示 橫坐標是對象的內存大小,這些值隨著不同對象是不同的,縱坐標是在某個內存大小上的對象的數量

下面我們來發現有內存泄漏的單例例子:
(1).旋轉屏幕前,我們看到已經分配的內存為814.617kb(手動GC):


image9.png

(2).旋轉屏幕后,我們看到已經分配的內存為956.891kb(手動GC):


image10.png

我們對比前后的兩次發現有內存不能被回收,也就是說旋轉屏幕導致內存泄漏了。這個工具沒法具體定位到內存泄漏的位置。

補充:Heap Viewer不光可以用來檢測是否有內存泄漏,對于內存抖動,我們也可以用該工具檢測,因為內存抖動的時候,會頻繁發生GC,這個時候我們只需要開啟Heap Viewer,觀察數據的變化,如果發生內存抖動,會觀察到數據在段時間內頻繁更新


3.MAT

全稱為Memory Analyzer Tool,一款詳細分析Java堆內存的工具,該工具非常強大,為了使用該工具,我們需要hprof文件。但是該文件不能直接被MAT使用,需要進行一步轉化,可以使用hprof-conv命令來轉化,但是Android Studio可以直接轉化.

下面我們就來那Heap Snapshot 中的hprof來分析:

(1).轉換hprof文件


image11.png

(2).使用Memory Analyzer Tool工具打開hprof文件


image12.png

工具會自動生成一個可疑的內存泄漏,其實這里對我們用處不大,我們主要分析overView選項卡。


image13.png

我們看到這里給出了一些基本的數據我大對象的圖,我們主要分析下面的Actions中的三個工具:
Histogram

主要是列出每個類中對象,點擊看下:


image14.png

我們看到這邊的對象有點多,我們選擇按照包來顯示,或者通過regex來篩選。
image15.png

找到我們要分析的類,選擇ListObject中的with incoming references,來顯示引用MainActivity的類。
image16.png

我們看到這邊有兩個地方引用了MainActivity,然后現在圖中的選項,排除所有的soft,weak,phantom引用,看看當前的被什么引用。我們來看下兩個結果:

image17.png
image18.png

我們看到一個被CommonUtil引用,導致內存泄漏,一個被InputMethodManger引用,導致內存泄漏,第二個是系統輸入法的bug,而第一個是我們自己寫的,如果列表中顯示很多我們只能一一分析。

上面是分析一個hprof來看,可能有時也看不出來,那么我們可以通過兩個hprof來對比分析。

對比分析

(1).將兩個hprof文件添加到工具中
(2).將兩個hprof文件添加到對比列表中


image19.png

(3).對比分析


image20.png
image21.png

我們看到經過旋轉操作,MainActivity有兩個,所以這邊肯定發生了內存泄漏,那到底是什么引起內存泄漏的呢?下面的分析步驟就和上面單獨分析一個hprof文件一樣了。

4.Allaction Tracking

Allocation Tracker(AS)工具比Allocation Tracker(Eclipse)工具強大的地方是更炫酷,更清晰,但是能做的事情都是一樣的。所以我們就分析Android Studio中的。

(1).Allocation Tracker啟動,生成alloc文件
image22.png
(2).分析alloc文件
image23.png

這邊有兩種顯示的方式:
*Group by Method:用方法來分類我們的內存分配
*Group by Allocator:用內存分配器來分類我們的內存分配
首先以線程對象分類,默認以分配順序來排序,當然你可以更改,只需在Size上點擊一下就會倒序,如果以Count排序也是一樣,Size就是內存大小,Count就是分配了多少次內存,點擊一下線程就會查看每個線程里所有分配內存的方法

當你以Group by Allocator來查看內存分配的情況時,詳細信息區域就會變成如下


image24.png

這種方式顯示的好處,是我們很好的定位我們自己的代碼的分析信息


分類旁邊還有跳轉到源碼的位置和統計圖。
輪胎圖

image25.png

輪胎圖是以圓心為起點,最外層是其內存實際分配的對象,每一個同心圓可能被分割成多個部分,代表了其不同的子孫,每一個同心圓代表他的一個后代,每個分割的部分代表了某一帶人有多人,你雙擊某個同心圓中某個分割的部分,會變成以你點擊的那一代為圓心再向外展開。如果想回到原始狀態,雙擊圓心就可以了。

柱狀圖
柱狀圖以左邊為起始點,從左到右的順序是某個的堆棧信息順序,縱坐標上的寬度是以其Count/Size的大小決定的。柱狀圖的內容其實和輪胎圖沒什么特別的地方


image26.png

5.TraceView

從代碼層面分析性能問題,針對每個方法來分析,比如當我們發現我們的應用出現卡頓的時候,我們可以來分析出現卡頓時在方法的調用上有沒有很耗時的操作.
主要是下面兩個問題:

  • 調用次數不多,但是每一次執行都很耗時
  • 方法耗時不大,但是調用次數太多

簡單一點來說就是我們能找到頻繁被調用的方法,也能找到執行非常耗時的方法,前者可能會造成Cpu頻繁調用,手機發燙的問題,后者就是卡頓的問題.

(1).打開Android device monitor,選中我們的應用,點擊start method profiling,開始trace
image30.png
(2).操作我們的應用,再次點擊上面的按鈕,生成trace文件
image31.png

traceview的面板分上下兩個部分:
*時間線面板以每個線程為一行,右邊是該線程在整個過程中方法執行的情況
*分析面板是以表格的形式展示所有線程的方法的各項指標

時間線面板
左邊是線程信息,main線程就是Android應用的主線程,這個線程是都會有的,其他的線程可能因操作不同而發生改變.每個線程的右邊對應的是該線程中每個方法的執行信息,左邊為第一個方法執行開始,最右邊為最后一個方法執行結束,其中的每一個小立柱就代表一次方法的調用,你可以把鼠標放到立柱上,就會顯示該方法調用的詳細信息,你可以隨意滑動你的鼠標,滑倒哪里,左上角就會顯示該方法調用的信息。

分析面板
面板列名含義:

    Name    方法的詳細信息,包括包名和參數信息
    Incl Cpu Time   Cpu執行該方法該方法及其子方法所花費的時間
    Incl Cpu Time % Cpu執行該方法該方法及其子方法所花費占Cpu總執行時間的百分比
    Excl Cpu Time   Cpu執行該方法所話費的時間
    Excl Cpu Time % Cpu執行該方法所話費的時間占Cpu總時間的百分比
    Incl Real Time  該方法及其子方法執行所話費的實際時間,從執行該方法到結束一共花了多少時間
    Incl Real Time %    上述時間占總的運行時間的百分比
    Excl Real Time %    該方法自身的實際允許時間
    Excl Real Time  上述時間占總的允許時間的百分比
    Calls+Recur 調用次數+遞歸次數,只在方法中顯示,在子展開后的父類和子類方法這一欄被下面的數據代替
    Calls/Total 調用次數和總次數的占比
    Cpu Time/Call   Cpu執行時間和調用次數的百分比,代表該函數消耗cpu的平均時間
    Real Time/Call  實際時間于調用次數的百分比,該表該函數平均執行時間

6.LeakCanary

quare公司開發的可以直接在手機端查看內存泄露的工具
實現原理:本質上還是用命令控制生成hprof文件分析檢查內存泄露。
GitHub:https://github.com/square/leakcanary

使用:

(1).添加如下依賴
    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
(2).添加Application子類

首先創建一個ExampleApplication,該類繼承于Application,在該類的onCreate方法中添加如下代碼開啟LeakCanary監控:

    LeakCanary.install(this);

具體的就不在說了,網上有很多,使用起來先對比較簡單。

7.Lint

android stidio 自帶的工具,功能很強大。
主要功能:

  • 檢測資源文件是否有沒有用到的資源。
  • 檢測常見內存泄露
  • 安全問題SDK版本安全問題
  • 是否有沒有使用的代碼
  • 代碼的規范
  • 自動生成的羅列出來
  • 提示去除沒用的導包
  • 提示可能的bug
image27.png

點擊inpsect code,工具就會自動分析你的項目代碼。


image28.png

(1). correctness 有錯誤的代碼
(2). performance 性能方面
(3). security 安全方面,常見的是備份
(4). usability 應該使用的方式
(5).class structure 類結構問題
(6). control flow issues 控制流程問題
(7). declaration redundancy 聲明冗余
(8). imports 提示去除沒用的導包
(9). probable bugs 可能的bug
(10). spelling 代碼的規范,駝峰命名法等

我們主要看下內存泄漏有沒有提示:


image29.png

我們看到這里直接提示我們可能出現的內存泄漏,很強大呀!

補充:在打包發布時,可以用Lint工具來去除多余的沒有使用的資源和類,來減小apk的體積。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內容

  • 每個人都有自己的秘密 秘密使人變的神秘 秘密使人變的更加謹慎 秘密使人變的更加努力 秘密使人變的更加強大 秘密使生...
    淡淡27閱讀 195評論 0 0
  • 1986年青島作為五個城市之一,列為單列經濟城市。什么叫單列呢?就是這類城市由中央來管轄師傅,是副省級的單位。 這...
    RGLR閱讀 270評論 0 0
  • DVWA-1.9系列一共分為10個功能模塊: Brute Force(暴力破解) Command Injectio...
    網絡安全自修室閱讀 1,412評論 0 0
  • 如果你從這篇文章中看到了你的影子,別太在意,我不是在寫你,但又有可能在寫你。 天暗了下來,是回家的時間了,我特意沒...
    解憂少年閱讀 525評論 11 7
  • 從前,一直聽身邊的同事在不同的場景中說,要學會換位思考。 給他人留有印象之時,也不是談起,要學會換位思考。 前段時...
    夏日嬤嬤茶1008閱讀 1,232評論 0 0