騰訊性能監(jiān)控Matrix

Matrix-android 當(dāng)前監(jiān)控范圍包括:應(yīng)用安裝包大小闷串,幀率變化,啟動(dòng)耗時(shí)筋量,卡頓烹吵,慢方法,SQLite 操作優(yōu)化桨武,文件讀寫肋拔,內(nèi)存泄漏等等。

  • APK Checker: 針對 APK 安裝包的分析檢測工具呀酸,根據(jù)一系列設(shè)定好的規(guī)則凉蜂,檢測 APK 是否存在特定的問題,并輸出較為詳細(xì)的檢測結(jié)果報(bào)告,用于分析排查問題以及版本追蹤
  • Resource Canary: 基于 WeakReference 的特性和 Square Haha 庫開發(fā)的 Activity 泄漏和 Bitmap 重復(fù)創(chuàng)建檢測工具
  • Trace Canary: 監(jiān)控ANR跃惫、界面流暢性叮叹、啟動(dòng)耗時(shí)、頁面切換耗時(shí)爆存、慢函數(shù)及卡頓等問題
  • SQLite Lint: 按官方最佳實(shí)踐自動(dòng)化檢測 SQLite 語句的使用質(zhì)量
  • IO Canary: 檢測文件 IO 問題蛉顽,包括:文件 IO 監(jiān)控和 Closeable Leak 監(jiān)控
  • Battery Canary: 監(jiān)控 App 活躍線程(待機(jī)狀態(tài) & 前臺(tái) Loop 監(jiān)控)、ASM 調(diào)用 (WakeLock/Alarm/Gps/Wifi/Bluetooth 等傳感器)先较、 后臺(tái)流量 (Wifi/移動(dòng)網(wǎng)絡(luò))等 Battery Historian 統(tǒng)計(jì) App 耗電的數(shù)據(jù)

特性

與常規(guī)的 APM 工具相比携冤,Matrix 擁有以下特點(diǎn):

APK Checker

  • 具有更好的可用性:JAR 包方式提供,更方便應(yīng)用到持續(xù)集成系統(tǒng)中闲勺,從而追蹤和對比每個(gè) APK 版本之間的變化
  • 更多的檢查分析功能:除具備 APKAnalyzer 的功能外曾棕,還支持統(tǒng)計(jì) APK 中包含的 R 類、檢查是否有多個(gè)動(dòng)態(tài)庫靜態(tài)鏈接了 STL 菜循、搜索 APK 中包含的無用資源翘地,以及支持自定義檢查規(guī)則等
  • 輸出的檢查結(jié)果更加詳實(shí):支持可視化的 HTML 格式,便于分析處理的 JSON 癌幕,自定義輸出等等

Resource Canary

  • 分離了檢測和分析部分衙耕,便于在不打斷自動(dòng)化測試的前提下持續(xù)輸出分析后的檢測結(jié)果
  • 對檢測部分生成的 Hprof 文件進(jìn)行了裁剪,移除了大部分無用數(shù)據(jù)勺远,降低了傳輸 Hprof 文件的開銷
  • 增加了重復(fù) Bitmap 對象檢測橙喘,方便通過減少冗余 Bitmap 數(shù)量,降低內(nèi)存消耗

Trace Canary

  • 編譯期動(dòng)態(tài)修改字節(jié)碼, 高性能記錄執(zhí)行耗時(shí)與調(diào)用堆棧
  • 準(zhǔn)確的定位到發(fā)生卡頓的函數(shù)胶逢,提供執(zhí)行堆棧厅瞎、執(zhí)行耗時(shí)、執(zhí)行次數(shù)等信息初坠,幫助快速解決卡頓問題
  • 自動(dòng)涵蓋卡頓和簸、啟動(dòng)耗時(shí)、頁面切換某筐、慢函數(shù)檢測等多個(gè)流暢性指標(biāo)
  • 準(zhǔn)確監(jiān)控ANR比搭,并且能夠高兼容性和穩(wěn)定性地保存系統(tǒng)產(chǎn)生的ANR Trace文件

SQLite Lint

  • 接入簡單冠跷,代碼無侵入
  • 數(shù)據(jù)量無關(guān)南誊,開發(fā)、測試階段即可發(fā)現(xiàn)SQLite性能隱患
  • 檢測算法基于最佳實(shí)踐蜜托,高標(biāo)準(zhǔn)把控SQLite質(zhì)量*
  • 底層是 C++ 實(shí)現(xiàn)抄囚,支持多平臺(tái)擴(kuò)展

IO Canary

  • 接入簡單,代碼無侵入
  • 性能橄务、泄漏全面監(jiān)控幔托,對 IO 質(zhì)量心中有數(shù)
  • 兼容到 Android P

Battery Canary

  • 接入簡單,開箱即用
  • 預(yù)留 Base 類和 Utility 工具以便擴(kuò)展監(jiān)控特性

Memory Hook

  • 一個(gè)檢測 Android native 內(nèi)存泄漏的工具
  • 無侵入,基于 PLT-hook(iqiyi/xHook)重挑,無需重編 native 庫
  • 高性能嗓化,基于 Wechat-Backtrace 進(jìn)行快速 unwind 堆棧,支持 aarch64 和 armeabi-v7a 架構(gòu)

Pthread Hook

  • 一個(gè)檢測 Android Java 和 native 線程泄漏及縮減 native 線程椕В空間的工具
  • 無侵入刺覆,基于 PLT-hook(iqiyi/xHook),無需重編 native 庫
  • 通過對 native 線程的默認(rèn)棧大小進(jìn)行減半降低線程帶來的虛擬內(nèi)存開銷史煎,在 32 位環(huán)境下可緩解虛擬內(nèi)存不足導(dǎo)致的崩潰問題

WVPreAllocHook

  • 一個(gè)用于安全釋放 WebView 預(yù)分配內(nèi)存以在不加載 WebView 時(shí)節(jié)省虛擬內(nèi)存的工具谦屑,在 32 位環(huán)境下可緩解虛擬內(nèi)存不足導(dǎo)致的崩潰問題
  • 無侵入,基于 PLT-hook(iqiyi/xHook)篇梭,無需重編 native 庫
  • 使用該工具后 WebView 仍可正常工作

Backtrace Component

  • 基于 DWARF 以及 ARM 異常處理數(shù)據(jù)進(jìn)行簡化并生成全新的 quicken unwind tables 數(shù)據(jù)氢橙,用于實(shí)現(xiàn)可快速回溯 native 調(diào)用棧的 backtrace 組件√裢担回溯速度約是 libunwindstack 的 15x ~ 30x 左右悍手。

使用方法

由于 JCenter 服務(wù)將于 2022 年 2 月 1 日下線,我們已將 Matrix 新版本(>= 0.8.0) maven repo 發(fā)布至 MavenCentral袍患。

  1. 在你項(xiàng)目根目錄下的 gradle.properties 中配置要依賴的 Matrix 版本號谓苟,如:
  MATRIX_VERSION=2.0.1
  1. 在你項(xiàng)目根目錄下的 build.gradle 文件添加 Matrix 依賴,如:
  dependencies {
      classpath ("com.tencent.matrix:matrix-gradle-plugin:${MATRIX_VERSION}") { changing = true }
  }
  1. 接著协怒,在 app/build.gradle 文件中添加 Matrix 各模塊的依賴涝焙,如:
  dependencies {
    implementation group: "com.tencent.matrix", name: "matrix-android-lib", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-android-commons", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-trace-canary", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-resource-canary-android", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-resource-canary-common", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-io-canary", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-sqlite-lint-android-sdk", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-battery-canary", version: MATRIX_VERSION, changing: true
    implementation group: "com.tencent.matrix", name: "matrix-hooks", version: MATRIX_VERSION, changing: true
  }

  apply plugin: 'com.tencent.matrix-plugin'
  matrix {
    trace {
        enable = true   //if you don't want to use trace canary, set false
        baseMethodMapFile = "${project.buildDir}/matrix_output/Debug.methodmap"
        blackListFile = "${project.projectDir}/matrixTrace/blackMethodList.txt"
    }
  }

目前 Matrix gradle plugin 支持 Android Gradle Plugin 3.5.0/4.0.0/4.1.0。

  1. 實(shí)現(xiàn) PluginListener孕暇,接收 Matrix 處理后的數(shù)據(jù), 如:
  public class TestPluginListener extends DefaultPluginListener {
    public static final String TAG = "Matrix.TestPluginListener";
    public TestPluginListener(Context context) {
        super(context);

    }

    @Override
    public void onReportIssue(Issue issue) {
        super.onReportIssue(issue);
        MatrixLog.e(TAG, issue.toString());

        //add your code to process data
    }
}
  1. 實(shí)現(xiàn)動(dòng)態(tài)配置接口仑撞, 可修改 Matrix 內(nèi)部參數(shù). 在 sample-android 中 我們有個(gè)簡單的動(dòng)態(tài)接口實(shí)例DynamicConfigImplDemo.java, 其中參數(shù)對應(yīng)的 key 位于文件 MatrixEnum中, 摘抄部分示例如下:
  public class DynamicConfigImplDemo implements IDynamicConfig {
    public DynamicConfigImplDemo() {}

    public boolean isFPSEnable() { return true;}
    public boolean isTraceEnable() { return true; }
    public boolean isMatrixEnable() { return true; }
    public boolean isDumpHprof() {  return false;}

    @Override
    public String get(String key, String defStr) {
        //hook to change default values
    }

    @Override
    public int get(String key, int defInt) {
         //hook to change default values
    }

    @Override
    public long get(String key, long defLong) {
        //hook to change default values
    }

    @Override
    public boolean get(String key, boolean defBool) {
        //hook to change default values
    }

    @Override
    public float get(String key, float defFloat) {
        //hook to change default values
    }
}

  1. 選擇程序啟動(dòng)的位置對 Matrix 進(jìn)行初始化妖滔,如在 Application 的繼承類中隧哮, Init 核心邏輯如下:
  Matrix.Builder builder = new Matrix.Builder(application); // build matrix
  builder.pluginListener(new TestPluginListener(this)); // add general pluginListener
  DynamicConfigImplDemo dynamicConfig = new DynamicConfigImplDemo(); // dynamic config

  // init plugin 
  IOCanaryPlugin ioCanaryPlugin = new IOCanaryPlugin(new IOConfig.Builder()
                    .dynamicConfig(dynamicConfig)
                    .build());
  //add to matrix               
  builder.plugin(ioCanaryPlugin);

  //init matrix
  Matrix.init(builder.build());

  // start plugin 
  ioCanaryPlugin.start();

至此,Matrix就已成功集成到你的項(xiàng)目中座舍,并且開始收集和分析性能相關(guān)異常數(shù)據(jù)沮翔,如仍有疑問,請查看 示例.

PS:

  1. 從 v0.9.0 開始曲秉,Matrix for Android 遷移到了 AndroidX. 你可能需要添加 'android.useAndroidX=true' 標(biāo)志到 gradle.properties 文件里采蚀。
  2. Matrix 分析后的輸出字段的含義請查看 Matrix 輸出內(nèi)容的含義解析

Battery Canary Usage

相關(guān)初始化代碼如下:

BatteryMonitorConfig config = new BatteryMonitorConfig.Builder()
        .enable(JiffiesMonitorFeature.class)
        .enableStatPidProc(true)
        .greyJiffiesTime(30 * 1000L)
        .setCallback(new BatteryMonitorCallback.BatteryPrinter())
        .build();

BatteryMonitorPlugin plugin = new BatteryMonitorPlugin(config);

具體使用方式,請參考單元測試?yán)锵嚓P(guān)用例的代碼: com.tencent.matrix.batterycanary.ApisTestsample.tencent.matrix.battery.BatteryCanaryInitHelper.

Backtrace Component Usage

如何初始化 backtrace 組件:

WeChatBacktrace.instance().configure(getApplicationContext()).commit();

初始化后其他 Matrix 組件就可以使用 Quicken Backtrace 進(jìn)行回溯承二。更多參數(shù)的配置請查看 WeChatBacktrace.Configuration 的接口注釋榆鼠。

APK Checker

APK Check 以獨(dú)立的 jar 包提供 (matrix-apk-canary-2.0.1.jar),你可以運(yùn)行:

java -jar matrix-apk-canary-2.0.1.jar

查看 Usages 來使用它亥鸠。

Usages: 
    --config CONFIG-FILE-PATH
or
    [--input INPUT-DIR-PATH] [--apk APK-FILE-PATH] [--unzip APK-UNZIP-PATH] [--mappingTxt MAPPING-FILE-PATH] [--resMappingTxt RESGUARD-MAPPING-FILE-PATH] [--output OUTPUT-PATH] [--format OUTPUT-FORMAT] [--formatJar OUTPUT-FORMAT-JAR] [--formatConfig OUTPUT-FORMAT-CONFIG (json-array format)] [Options]

Options:
-manifest
     Read package info from the AndroidManifest.xml.
-fileSize [--min DOWN-LIMIT-SIZE (KB)] [--order ORDER-BY ('asc'|'desc')] [--suffix FILTER-SUFFIX-LIST (split by ',')]
     Show files whose size exceed limit size in order.
-countMethod [--group GROUP-BY ('class'|'package')]
     Count methods in dex file, output results group by class name or package name.
-checkResProguard
     Check if the resguard was applied.
-findNonAlphaPng [--min DOWN-LIMIT-SIZE (KB)]
     Find out the non-alpha png-format files whose size exceed limit size in desc order.
-checkMultiLibrary
     Check if there are more than one library dir in the 'lib'.
-uncompressedFile [--suffix FILTER-SUFFIX-LIST (split by ',')]
     Show uncompressed file types.
-countR
     Count the R class.
-duplicatedFile
     Find out the duplicated resource files in desc order.
-checkMultiSTL  --toolnm TOOL-NM-PATH
     Check if there are more than one shared library statically linked the STL.
-unusedResources --rTxt R-TXT-FILE-PATH [--ignoreResources IGNORE-RESOURCES-LIST (split by ',')]
     Find out the unused resources.
-unusedAssets [--ignoreAssets IGNORE-ASSETS-LIST (split by ',')]
     Find out the unused assets file.
-unstrippedSo  --toolnm TOOL-NM-PATH
     Find out the unstripped shared library file.

由于篇幅影響妆够,此次不再贅述识啦,我們在 Matrix-APKChecker 中進(jìn)行了詳細(xì)說明。

參加文章:
http://www.reibang.com/p/0db4a02d6ca7

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末神妹,一起剝皮案震驚了整個(gè)濱河市颓哮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鸵荠,老刑警劉巖题翻,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異腰鬼,居然都是意外死亡嵌赠,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進(jìn)店門熄赡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來姜挺,“玉大人,你說我怎么就攤上這事彼硫〈逗溃” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵拧篮,是天一觀的道長词渤。 經(jīng)常有香客問我,道長串绩,這世上最難降的妖魔是什么缺虐? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮礁凡,結(jié)果婚禮上高氮,老公的妹妹穿的比我還像新娘。我一直安慰自己顷牌,他們只是感情好剪芍,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著窟蓝,像睡著了一般罪裹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上运挫,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天状共,我揣著相機(jī)與錄音,去河邊找鬼滑臊。 笑死口芍,一個(gè)胖子當(dāng)著我的面吹牛箍铲,可吹牛的內(nèi)容都是我干的雇卷。 我是一名探鬼主播,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼关划!你這毒婦竟也來了小染?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤贮折,失蹤者是張志新(化名)和其女友劉穎裤翩,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體调榄,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡踊赠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了每庆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片筐带。...
    茶點(diǎn)故事閱讀 37,997評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖缤灵,靈堂內(nèi)的尸體忽然破棺而出伦籍,到底是詐尸還是另有隱情,我是刑警寧澤腮出,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布就轧,位于F島的核電站渊涝,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜哼鬓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望歧强。 院中可真熱鬧哪廓,春花似錦、人聲如沸侣滩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽君珠。三九已至寝志,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間策添,已是汗流浹背材部。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留唯竹,地道東北人乐导。 一個(gè)月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像浸颓,于是被迫代替她去往敵國和親物臂。 傳聞我的和親對象是個(gè)殘疾皇子旺拉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容