以前作为app开发者,能够经过Android Studio自带的app profiler来检查单一使用的performance状况。比方内存占用,网络请求等等

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

可是成为framework开发之后,就不能只局限于单一的使用的profiler了。因为一个app的performance其实也取决于当时体系的运转状况。比方敞开某一个线程运转耗时操作,这个线程到底在某一个短时刻内分配了多少CPU cycle,决议了它多快能运转完成。当体系反常繁忙的时分,单一线程所能分配到的cycle自然变少。

所以今日我就简略的介绍一下一个能够profile整个体系的运转状况的东西Perfetto, 来看看怎样监控整个体系的performance。这期文章会以监控线程运转状况,Binder call为重点。

Perfetto初探

Perfetto 是谷歌推出的新一代体系级别performance的监控东西(能够监控Linux和Android),

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

详细的用处和用法能够参考官网 : perfetto.dev/

简略的说,开发者能够经过一个比较傻瓜式的网站UI tool来提取 trace文件,也能够用一个script自行装备。可是原理都是一样的,经过修改data source 来提供想监控的状况。

经过UI东西监控

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

经过script监控

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

值得注意的是Perfetto默认不监控binder和一切app的trace,在这儿咱们需求改动一下装备敞开监控binder和一切app的trace。然后咱们也能够自定义duration_ms字段来操控profile的时刻长短。我作业的时分需求监控接听电话的performance,所以我一般设置成30秒。

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

敞开监控之后,立刻进行想监控的操作(无论是app的行为,仍是体系的行为),然后Perfetto东西会自动翻开一个可视化的网站剖析得到的监控trace文件。Trace文件可视化之后长这个姿态:

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

左边一列列出了在当时监控session之内敞开的一切进程。咱们能够借此检查咱们想检查的app/进程的运转状况。

点击某一个进程,左边会列出在监控session中发动的一切线程和线程中记载的trace(下面会详细讲一下trace)

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

怎样加Trace

Trace代表了一段你想监控的代码段。在Perfetto 可视化东西里边长这样。

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

以上是一个大Trace里边包括了许多小Trace, 原因也很简略,一个有Trace的办法A能够包括若干个也带有Trace的办法B,C,D,E。。。

在代码里边加Trace也很简略,

new Thread(() -> {
    Trace.beginSection("test2");
    try{
        //模仿耗时作业
        Thread.sleep(4000);
    }
    catch (Exception e) {
    }
    Trace.endSection();
}, "richard").start();

加了这个代码之后,在Perfetto 可视化东西就能够看到该Trace

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

同理假如你在一个办法里边写多个Trace

new Thread(() -> {
    Trace.beginSection("test2");
    try{
        //模仿耗时作业
        Thread.sleep(2000);
        Trace.beginSection("test3");
        //模仿调用另一个带trace的办法
        Thread.sleep(2000);
        Trace.endSection();
    }
    catch (Exception e) {
    }
    Trace.endSection();
}, "richard").start();

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

所以,合理的编写trace代码能够轻松的在监控东西中检查办法调用的耗时和联系。

安卓在体系层许多的当地都加入了默认的trace,不过不少都需求体系开发者在代码中手动敞开,需求自己重新编译体系的ROM。比方Telecom component:

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

所以也侧面说明了,要想能合理的调试体系performance,其实要先有对要监控的部位的根底认知。。。。否则在哪打log,或许trace都不知道的话,光看现有的trace可能并不会特别有用。

最后安卓也支撑异步的trace。比方开始trace和结束trace在不同线程 (可是这种trace貌似出来检查耗时之外并不是特别有用,因为这种线程不同的状况下,trace会单独列出来不好线程绑定)

Trace.beginAsyncSection("test1", 1);
new Thread(new Runnable() {
    @Override
    public void run() {
        try{
            Thread.sleep(4000);
        }
        catch (Exception e) {
        }
        Trace.endAsyncSection("test1", 1);
    }
}, "richard").start();

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

线程运转状况

假如你仔细观察,会发现同一个线程会有两行。

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

其实这两行的意图是不一样的,榜首行一般记载线程的运转状况,第二行记载线程的trace。

咱们把榜首行放大看看

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

能够发现榜首行记载了线程在这个session中什么时分是running的状况(被分配了CPU cycle,在CPU中运转),什么时分是runnable的状况(没分配到CPU,在等候中)。

经过鼠标的拖拽,能够把某一段trace包起来,检查这个trace总体被分配的CPU状况

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

能够看到这一段trace里边,正在在CPU中运转的时刻只要10微秒左右,等候的时刻是运转的十倍左右。

假如这段代码不是故意的在代码中等候线程或许进行IO的话,说明当时线程被分配的CPU cycle不是很够。这便是值得注意需求优化的当地了。

Binder call的追寻

和以前的App profiler相比,Perfetto最大的提高之一便是在可视化东西中提供了Binder call的追寻。开发者能够检查任何一个IPC的caller 和 consumer。

比方咱们在App中调用体系API,去检查对某个体系API从哪里call,到哪个进程。

new Thread(new Runnable() {
    @Override
    public void run() {
        Trace.beginSection("test1");
        TelephonyManager manager = MainActivity.this.getSystemService(TelephonyManager.class);
        try{
            manager.getEmergencyNumberList();
            Thread.sleep(4000);
        }
        catch (Exception e) {
        }
        Trace.endSection();
    }
}, "richard").start();

以上代码中咱们调用了体系API TelephonyManager#getEmergencyNumberList, 敞开监控之后运转该代码,检查可视化东西

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

能够看到在trace test1 下面果然有一个binder call的trace,点击该trace的binder reply,可视化东西会自动跳转到binder的reply进程

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

能够看到该binder的reply是在com.android.phone(也便是Telephony)进程。

检查源代码的package name和 服务端完成

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

果然!!!

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)

经过监控binder call的trace,咱们作为体系开发者能够了解某个app在调用IPC的时分,为何会耗时,耗时的进程在哪,服务端的进程的运转状况等等,从而做出优化选择。

总结

这篇文章简略的介绍了一下Perfetto的使用办法,其实Perfetto除了以上三个用处还有许多强大的功用,这儿只做简略的介绍,下篇文章会用一个实际的比如来讲述怎样经过Perfetto 监控东西来发现能够优化的体系代码的 (呵呵又水了一篇文章!!!!!)

最近作业实在太忙了,更新速度肉眼可见变慢。。。。。。求宽恕

初学安卓framework系列 五 (监控系统的performance, 初探Perfetto工具)