Android卡顿

参考Awesome-Android-Interview

Demo:Advanced

线下调试

Linux命令

说到卡顿,主要都和 CPU 相关。刷了几篇CPU文章,造成卡顿的原因最终都会反映到 CPU 时间上。

CPU 时间分为两种:用户时间和系统时间。用户时间就是执行用户态应用程序代码所消耗的时间;系统时间就是执行内核态系统调用所消耗的时间,包括 I/O、锁、中断以及其他系统调用的时间。

Linux环境下进程的CPU占用率,获取手机cpu方法

E:\zt\project\jitpack\Advanced>adb shell
// 获取 CPU 核心数
heroqltechn:/ $ cat /sys/devices/system/cpu/possible
0-3
// 获取某个 CPU 的频率
heroqltechn:/ $ cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
1593600

 

Traceview

生成trace日志方法

使用 CPU Profiler 检查 CPU 活动

Traceview 可以用来查看整个过程有哪些函数调用,但是工具本身带来的性能开销过大,有时无法反映真实的情况。比如一个函数本身的耗时是 1 秒,开启 Traceview 后可能会变成 5 秒,而且这些函数的耗时变化并不是成比例放大。

 

Nanoscope

另外介绍一款,Uber 开源的Nanoscope就能达到这个效果。它的实现原理是直接修改 Android 虚拟机源码,在ArtMethod执行入口和执行结束位置增加埋点代码,将所有的信息先写到内存,等到 trace 结束后才统一生成结果文件。

但是它也有不少限制:需要自己刷 ROM,并且当前只支持 Nexus 6P,或者采用其提供的 x86 架构的模拟器。默认只支持主线程采集,其他线程需要代码手动设置。考虑到内存大小的限制,每个线程的内存数组只能支持大约 20 秒左右的时间段。

 

systrace

使用

利用了 Linux 的ftrace调试工具,相当于在系统各个关键位置都添加了一些性能探针,也就是在代码里加了一些性能监控的埋点。

systrace 跟踪系统的 I/O 操作、CPU 负载、Surface 渲染、GC 等事件。

systrace 工具有选择性或者采用抽样的方式观察某些函数调用过程,只能监控特定系统调用的耗时情况,而且性能开销非常低。但是它不支持应用程序代码的耗时分析,所以在使用时有一些局限性。

我们可以通过编译时给每个函数插桩的方式来实现,也就是在重要函数的入口和出口分别增加Trace.beginSection和Trace.endSection。

 

注意

AS在3.0之后删除之前的了 Tools目录下的Android菜单,这样就导致以前通过Tools——>Android——>DeviceMonitor打开DDMS的方式行不通啦

最后根据Google 文档自己鼓捣打开DDMS,在此记录一下:

1.先找到配置的SDK路径,我的是E:\android-sdk\sdk;

2.在SDK的android路径tools下monitor.bat 的批处理文件;

3.点击monitor.bat这个批处理文件,在屏幕上会打开一个类似CMD的命令行中输入板,然后迅速自动关闭

4.坐等1到3秒就会打开DDMS;

 

Simpleperf

分析 Native 函数的调用。

 

如果需要分析 Native 代码的耗时,可以选择 Simpleperf;如果想分析系统调用,可以选择 systrace;如果想分析整个程序执行流程的耗时,可以选择 Traceview 或者插桩版本的 systrace。

 

Profiler

Android Studio 3.2 的 Profiler 中直接集成了几种性能分析工具,其中:Sample Java Methods 的功能类似于 Traceview 的 sample 类型。Trace Java Methods 的功能类似于 Traceview 的 instrument 类型。Trace System Calls 的功能类似于 systrace。SampleNative (API Level 26+) 的功能类似于 Simpleperf。

 

线上监控

消息队列

通过替换 Looper 的 Printer 实现。

            final Printer logging = me.mLogging;
            if (logging != null) {
                logging.println(">>>>> Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
            }

AndroidPerformanceMonitor

也是BlockCanary原理,中文文档

通过一个监控线程,每隔一段时间向主线程消息队列的头部插入一条空消息,然后监测空消息是否被消费。

 

插桩

使用Hook 技术。

参考demo中的CartonActivity页面

            @TimeSpend("btnTime")
            @Override
            public void onClick(View v) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

输出日志
com.example.advanced E/TimeSpendAspect: 功能:btnTime,类的onClick方法执行了,用时1000 ms

Profilo

Facebook 开源了一个叫Profilo的库,集成 atrace 功能,快速获取 Java 堆栈。

demo项目地址

Profilo 的实现非常精妙,它实现类似 Native 崩溃捕捉的方式快速获取 Java 堆栈,通过间隔发送 SIGPROF 信号,整个过程如下图所示。

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值