1. 程式人生 > >Android 效能分析之TraceView使用(應用耗時分析)

Android 效能分析之TraceView使用(應用耗時分析)

文章概覽:

  • TraceView概述
  • trace檔案的3種生成方式
    • Android studio 直接生成(推薦)
    • 嵌入程式碼程式碼生成
    • 使用DDMS來生成
  • TraceView介面及引數介紹
  • 使用TraceView分析,定位問題
  • 相關資料

TraceView概述

Traceview是android平臺配備一個很好的效能分析的工具。它可以把trace檔案轉化為圖形,通過圖形化的方式讓我們瞭解我們要跟蹤的程式的效能。當你有一個trace 的日誌檔案時(通過在程式新增trace程式碼或使用DDMS或studio生成),你可以使用TraceView載入日誌檔案,Traceview 可以幫助你除錯你的應用和分析它的效能。

trace檔案的3種生成方式

  • 第一種,使用android studio 直接生成(推薦)操作: 1,點選Monitors–>CPU欄目上的小鬧鐘(如下圖),開始記錄。 2,操作你手機需要分析的功能。比如,UI卡頓那塊,應用耗時那塊.. 3,在此點選Monitors–>CPU欄目上的小鬧鐘(如下圖),結束記錄,這是會生成trace檔案。(可以點選studio 左側的Captures。它裡面的Method Tracing 裡面可以看到) 4,這個時候,studio會自動開啟這個trace檔案。(很可惜,這次說的不是它)

  • 第二種,嵌入程式碼程式碼生成 使用 android.os.Debug.startMethodTracing(String traceName); android.os.Debug.stopMethodTracing(); 這兩個方法新增到你想分析的那些程式碼中,當程式運行了這段程式碼,就會在/sdcard 目錄中生成一個traceName命名的trace檔案。

  • 第三種,使用DDMS來生成 1,選中Devices裡面,你想檢視的程序。然後點選,start Method Profiling,如下圖 2,操作你手機想除錯的那部分功能 3,再次點選那個按鈕Stop Method Profiling

TraceView介面及引數介紹

  • 介面說明 介面主要有上下兩個面板,上面是時間線面板,下面是分析面板。時間線面板描述了執行緒和方法的開始和結束,分析面板提供了一個方法中發生的情況資訊。時間線面板又可以分為兩個部分(左右),暫時分為三個部分。如下圖示記

    • 第一部分(上面板左側)

      資料中所採集的執行緒資訊,比如main執行緒等等

    • 第二部分(上面板的右側) 時間線上是每個執行緒在這個時間段內所涉及的函式呼叫資訊(空白的位置表示當時沒有在執行),每個方法用一種顏色顯示(顏色迴圈使用),當滑鼠放到不同的位置可以看到,當時執行執行的方法,以及相關資訊。
    • 第三部分(下方面版) 下半部分表示這段時間執行的方法,及每個方法執行的資訊分析(比如,佔用CPU的時間,呼叫、遞迴次數等等),參考引數說明  
  • 引數說明 下方面板中資料對應的列名(上圖紅框那一行)
    • Calls+RecurCalls/Total (重要) 某函式執行,呼叫、遞迴的次數
    • Cpu Time/Call (重要) 某函式執行,佔用CPU的時間
    • Real Time/Call (重要) 某函式執行,平均的執行時間
    • incl Cpu Time 某函式執行,佔用CPU的時間(包括其內部函式呼叫的時間)
    • Excl Cpu Time 某函式執行,佔用CPU的時間(不包括其內部函式呼叫的時間)
    • incl Real Time 某函式執行,執行的真實時間(不包括其內部函式呼叫的時間)
    • Excl Real Time 某函式執行,執行的真實時間(不包括其內部函式呼叫的時間)

使用TraceView分析,定位問題

上面給幾個引數標記了重要,下面我們來想下為什麼呢? 我們在分析耗時的時候一般有兩種情況: - 1,呼叫次數不多。但是,本身就非常耗時。 - 2,本身不是很耗時。但是,呼叫非常頻繁。

1,第一種情況,我們可以使用 Cpu Time 來檢視它的耗時情況。 2,第二種情況,我們可以使用 Calls+RecurCalls/Total 來檢視它的呼叫情況。

現在,我們模擬,使用CPU Time來分析

  • 第一步,點選CPU Time列,讓函式從高到底排列,並找到我們專案的方法點選進入,如下圖 我們發現裡面分為Parents和Children。 Parents:自身函式。 Children:呼叫內部的函式。 然後,我們找到了drawRegionV2的函式

  • 第二步,點選drawRegionV2函式,一步步找進去,getPoints()->toFloat(),最後,如下圖

  • 第三步,檢視我們的程式碼,並解決問題。 java程式碼

 @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        ...
        drawRegionV2(canvas);
        ...
    }

    ...

 private void drawRegionV2(Canvas canvas) {
        ...
        getPoints(mCenterPoint, mIdentityValue, mCreditValue, mCreditHistoryValue, mPepoleRelativeValue, mActionFavoriteValue);
        ...
    }
    ...
private ArrayList<PointF> getPoints(Point center, double mIdentityValue, double mCreditValue, double mCreditHistoryValue, double mPepoleRelativeValue, double mActionFavorite) {
        ArrayList<PointF> points = new ArrayList<>();
        points.add(new PointF(center.x, toFloat(center.y - mIdentityValue)));
        points.add(new PointF(toFloat(center.x + 100), toFloat(center.y - 100)));
        points.add(new PointF(toFloat(center.x +100), toFloat(center.y +100);
        points.add(new PointF(toFloat(center.x - 100), toFloat(center.y + 100)));
        points.add(new PointF(toFloat(center.x - 100), toFloat(center.y - 100)));
        return points;
    }
    ...
public float toFloat(double d) {
        BigDecimal bigDecimal = new BigDecimal(d);
        return bigDecimal.floatValue();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

最後,發現了ondraw裡面的toFloat()函式的BigDecimal。執行一次getPoints函式就會建立好幾個函式的BigDecimal物件,而且還是在Ondraw裡面。 分析到這裡,我們已經定位到問題了。

相關資料

--------------------- 本文來自 笨鳥-先飛 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/android_jianbo/article/details/76608558?utm_source=copy