Android卡顿优化

造成卡顿的原因有很多 最终会反映到CPU时间上
CPU时间分为两种:
1⃣️用户时间
执行用户态应用程序代码消耗的时间
2⃣️系统时间
执行内核态系统调用所消耗的时间 包括 I/O 锁 中断以及其他系统调用的时间

CPU性能

评价CPU的性能 需要看主频 核心数 缓存等参数
获取CPU信息:

// 获取 CPU 核心数
cat /sys/devices/system/cpu/possible  

// 获取某个 CPU 的频率
cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq

卡顿问题分析指标

查看CPU的使用率 可以通过 /proc/stat 得到整个系统的CPU使用情况 通过 /proc/[pid]/stat得到某个进程的CPU使用情况

proc/self/stat:
  utime:       用户时间,反应用户代码执行的耗时  
  stime:       系统时间,反应系统调用执行的耗时
  majorFaults:需要硬盘拷贝的缺页次数
  minorFaults:无需硬盘拷贝的缺页次数

如果CPU使用率大于60% 表示系统处于繁忙状态 需要进一步分析用户时间和系统时间的比例
对于普通应用程序 系统时间不会长期高于30% 如果超过 应该进一步检查是否I/O过多 还是其他系统调用问题

相关工具:
top 命令 查看哪个进程是CPU的消耗大户
vmstat 命令 实时动态监视操作系统的虚拟内存和CPU
strace 命令 跟踪某个进程中所有的系统调用

除了需要查看CPU的使用率还需要查看CPU饱和度(线程排队等待CPU的情况 也就是CPU的负载情况)
CPU饱和度首先和应用的线程数有关 如果启动的线程过多 容易导致系统不断切换执行的线程 把大量的时间浪费在上下文切换 每一次CPU上下文切换都需要刷新寄存器和计数器 至少需要几十纳秒的时间

可以通过使用 vmstat 命令或者 /proc/[pid]/schedstat 文件来查看CPU上下文切换次数 特别需要注意 nr_involuntary_switches被动切换的次数

proc/self/sched:
  nr_voluntary_switches:     
  主动上下文切换次数,因为线程无法获取所需资源导致上下文切换,最普遍的是 IO。    
  nr_involuntary_switches:   
  被动上下文切换次数,线程被系统强制调度导致上下文切换,例如大量线程在抢占 CPU。
  se.statistics.iowait_count:IO 等待的次数
  se.statistics.iowait_sum:  IO 等待的时间

通过uptime 命令可以检查 CPU在1分钟 5分钟 和15分钟内的平均负载 比如一个4核的CPU 如果当前平均负载是8 表明每个CPU又来了一个线程在运行 还有一个线程在等待
一般平均来负载应该控制在 0.7*核数 以内

另外一个影响CPU饱和度的是 线程优先级 线程优先级会影响Android系统的调度策略 主要由 nicecgroup 类型共同决定 nice值越低 抢占CPU时间片的能力越强 当CPU空闲时 线程的优先级对执行效率的影响不会特别明显 但是在CPU繁忙时 影响就非常大

关于线程优先级 需要注意是否存在高优先级的线程空等低优先级线程,例如主线程等待某个后台线程的锁
从应用程序的角度看 用户时间 系统时间 等待CPU的调度 都是程序运行花费的时间

Android卡顿排查工具

Traceview systrace
从实现上分两个流派:
1⃣️ instrument 获取一段时间内所欲呕函数的调用过程 分析这个过程进一步分析优化的点
2⃣️ sample 有选择性或者采用抽样的方式观察某些函数的调用过程 分析可疑点

  • Traceview
    利用Android Runtime函数调用event事件 将函数运行的耗时和调用关系写入trace 文件中
    属于instrument 可以查看整个过程有哪些函数调用 但是本身性能开销大
    Android 5.0 之后 新增了startMethodTracingSampling 方法 使用基于样本的方式进行分析 以减少对运行时的性能影响

  • Nanoscope
    instrument 类型的性能分析工具 性能损耗较小
    原理是 直接修改Android虚拟机源码 在ArtMethod 执行入口和执行结束位置增加卖点代码 将所有的信息先写到内存 等到trace结束后才统一生成结果文件
    限制:
    1⃣️ 需要自己刷ROM 并且当前只支持Nexus 6P 或者对应的模拟器
    2⃣️ 默认只支持主线程采集 其他线程需要代码手动设置
    非常适合做启动耗时时的自动化分析
    生成的是符合Chrome tracing规范的HTML文件 可以通过脚本来实现两个功能:
    1⃣️ 反混淆 通过mapping自动反混淆结果文件
    2⃣️ 自动化分析 传入相同的起点和终点 实现两个结果文件的diff 自动分析差异

  • systrace
    可以跟踪系统的I/O操作 CPU负载 Surface渲染 GC
    利用了Linux的ftrace 调试工具 相当于在系统各个位置添加了一些性能探针
    Android 在ftrace的基础上封装了atrace 增加了更多特有的探针 如 Graphics、Activity Manager、Dalvik VM、System Server

只能监听特定系统调用的耗时情况 所以属于sample类型 性能开销很低 不支持应用程序代码的耗时分析

  • Simpleperf
    分析Native函数的调用 属于sample类型 性能开销很低
    利用CPU的性能监控单元(PMU)提供的硬件perf事件
    使用Simpleperf可以看到所有的Native代码的耗时 例如加载dex vertify class

Simpleperf同时封装了systrace的监控功能
发展的几个阶段:
第一个阶段:在Android M和以前 Simpleperf不支持Java代码分析
第二个阶段:在Android O和以前 需要手动编译OAT文件
第三个阶段:在Android P以后 Simpleperf支持Java代码分析

除了Nanoscope之外的工具都只支持debugable的应用程序 需要root才能测试release包

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

可视化方法

Android Studio 3.2 的Profiler中集成了几种性能分析工具:

  • Sample Java Methods 的功能类似于Traceviewsample类型
  • Trace Java Methods 类似Traceviewinstrument类型
  • Trace System Calls 类似systrace
  • SampleNative(API Level 26+) 类似 Simpleperf

这些工具都支持Call ChartFlame Chart 两种展示方式

  • Call Chart Traceview 和 systrace 默认使用的展示方式 按照应用程序的函数执行顺序来展示 适合分析整个流程的调用
  • Flame Chart 火焰图 以全局视野看待一段时间的调用分布s s s
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容