Android卡顿掉帧问题分析之工具篇

本文详细介绍了Android系统级性能分析工具Systrace。阐述其内容结构,涵盖CPU、渲染显示、系统框架进程和应用进程等信息区域;分享分析技巧,如线程状态转换和等待唤醒关系分析,以及添加自定义tag方法;简介原理,涉及ftrace机制和atrace运行原理;还提及抓取方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

“工欲善其事,必先利其器”,在开始着手分析卡顿问题之前,我们还必须要掌握一些分析性能问题的工具与手段,也就是掌握分析问题所使用的“器”,才能帮助我们更好的观测系统运行的状态,找到性能问题的原因。Systrace 是谷歌提供的最常用的Android 系统级性能分析工具。它以视觉化的方式将系统内所有的“工作线程”(内核+框架+应用)与系统模块状态(如 CPU 调度、IO 活动、Binder 调用等信息)按时间轴铺开展示,并支持在 Chrome 浏览器中显示出来。在 Perfetto 出现之前,它是最实用、分析最精准、最专业的性能分析工具,是分析Android性能问题的首选。本文我们就来详细分析一下这个Systrace工具 。

1 Systrace内容结构

Systrace 可以收集Android关键子系统(如CPU调度、SurfaceFlinger渲染系统、System Server系统框架、Input系统等)的运行信息,并以图像的形式按照时间轴铺开展示出来,帮助开发者直观的看到整个系统的运行状态,从而分析出系统的性能问题瓶颈所在。其界面展示的主要信息区域如下:

1.1 CPU Trace信息区域

如上图所示,Systrace 中 CPU Trace一般在最上面显示,展示Kernel中的 CPU Info 区域信息,一般包含如下信息:

  1. CPU的组成架构,包含多少颗CPU运行核心,以及编号信息。
  2. 每颗CPU核心的实时运行频率信息;
  3. 每颗CPU核心当前支持的运行频率的最高与最低的门限值;
  4. 每颗CPU核心的状态信息,是否进入节能或断电关闭状态;
  5. 每颗CPU核心上运行的线程任务信息与统计,按时间轴排开

总的来说,Systrace 中的CPU Trace 这里一般是看任务调度信息,查看是否是CPU频率或者是CPU调度逻辑导致当前任务出现性能问题,举例如下:

  1. 某个场景的任务执行比较慢,我们就可以查看是不是这个任务被CPU调度器安排到了小核上运行?
  2. 某个场景的任务执行比较慢,当前执行这个任务的 CPU 运行频率是不是不够?是否因为门限值的设置不合理导致CPU被限频了?
  3. 我的任务对性能要求比较高,比如指纹解锁,能不能把我这个任务持续放到CPU超大核去运行?
  4. 我的前台应用任务线程长时间处于Runnable状态无法执行而卡顿,当前到底是什么任务在抢占了CPU资源在运行?

1.2 渲染显示系统信息区域

在这篇文章Android卡顿掉帧问题分析之原理篇-CSDN博客我们完整的分析了Android应用上帧显示的全部流程,其中包含了Android渲染显示系统的核心逻辑,这部分内容在Systrace上也有完整的展示,如下图所示:

从上面的Systrace截图中我们可以看到一个屏幕Vsync周期内(屏幕刷新率60HZ条件下就是16.6ms),应用上帧渲染显示的完整流程信息:

  1. Vsync app信号到来后唤醒应用AppUI线程,开始执行一帧画面的measurelayoutdraw绘制等动作;
  2. HWUI硬件加速默认开启的条件下,应用AppUI线程完成draw绘制动作后就会唤醒其RenderThread渲染线程,触发其使用SkiaOpenGL渲染管道执行一帧数据的渲染操作,渲染完成后通过Binder调用queueBuffer接口将Buffer画面缓存数据提交到SurfaceFlinger进程;
  3. SurfaceFlinger进程中在收到应用queueBuffer上帧请求后,会先将对应的应用Layer中的BufferQueue中的Buffer置为Queued状态,标识应用“生产”了一帧Buffer画面数据,然后通过requestNextVsync注册下一个Vsync sf信号;
  4. Vsync sf信号到达后,会及时唤醒SurfaceFlinger进程的主线程执行一帧的合成任务,其中会先遍历所有的Layer图层缓存区,找到处于Queued状态的新提交的缓存区,将其置为Acquired状态,标识“消费”了一帧Buffer画面数据;然后Binder唤醒HWC service进程的工作线程执行具体的图层的合成送显操作;

总的来说,Systrace中的渲染显示系统这部分能够帮助我们判断界面是否有掉帧以及掉帧产生原因的分析方向,主要分析流程如下图所示:

1.3 System Server框架进程信息区域

1.3.1 Input

Input System Server 进程中非常重要的一部分,主要是由 InputReader InputDispatcher 这两个 Native 子线程组成,关于这一部分在上一篇文章中已经从原理机制并结合Systrace详细分析过,这里就不再展开分析。我们回顾一下这边部分内容在Systrace上的表现:

1.3.2 ActivityManagerService

ActivityManagerService(以下简称AMS)属于系统框架System Server中运行的核心服务之一,主要负责应用进程和四大组件的管理。是与应用App进程之间产生Binder交互最多的系统服务之一。谷歌原生的AOSP代码中就在AMS服务管理的进程和四大组件的各种场景下有对应的Trace点来记录,比如大家熟悉的 ActivityStartActivityResumeactivityStop 等,与AMS相关的Trace一般会用TRACE_TAG_ACTIVITY_MANAGER这个TAG,在 Systrace 中对应的名字是 ActivityManager 。以桌面打开应用冷启动场景为例,AMS需要为应用创建一个新的进程,此过程在AOSP代码中就有相关的AMS相关的Trace埋点记录,如下图所示:

对应Systrace上表现如下图所示:

1.3.3 WindowManagerService

WindowManagerService(以下简称WMS) 属于系统框架System Server中运行的核心服务之一,主要负责应用窗口管理、窗口动画管理、Surface管理和Input触控事件的管理。也是与应用App进程之间产生Binder交互最多的系统服务之一。谷歌原生的AOSP代码中就在WMS窗口管理等核心流程上有对应的Trace Tag埋点来记录。与WMS 相关的 Trace 一般会用 TRACE_TAG_WINDOW_MANAGER 这个 TAG, 在 Systrace 中对应的名字是 WindowManager 。继续以上面的桌面打开应用冷启动场景为例,应用启动后创建第一个Activity界面后,在绘制第一帧画面时需要通过Binder访问框架WMS服务的relayoutWindow接口,以实现计算应用窗口的大小和申请一张可用Surface画布等逻辑,从Systrace上看如下图所示:

1.3.4 HandlerThread核心工作线程

上面描述的AMSWMS等系统框架核心管理服务,其具体逻辑最终都需要运行在具体的线程中。为此system_server进程中设计了很多继承于HandlerThread(自带Looper消息循环的线程)的核心工作线程,负责执行不同分类业务的逻辑。比如有专门负责系统UI展示的UiThread线程(源码实现位于framework/base/services/core/java/com/android/server/UiThread.java),线程名为“android.ui”,在Systrace上的显示如下图所示:



比如负责窗口动画展示的AnimationThread,线程名为“android.anim”,在Systrace上的显示如下图所示:

还有很多,比如负责IO处理的工作线程“android.io”,再比如拥有极高优先级,负责系统界面实时显示的工作线程“android.display”等,由于篇幅所限,就不再一一展开分析,感兴趣的读者可以自行结合源码去阅读。随着对系统源码逻辑的深入了解,相信对这些框架的核心工作线程也会越来越熟悉。

由于这些自带消息循环的核心工作线程中执行的都是系统框架system_server进程中的核心逻辑,所以这些工作线程运行的是否通畅直接关系到系统的“健康程度”。通过从Systrace上观察这些工作线程的运行任务负载就可以直接反映出系统框架的负载与繁忙程度,如果这些线程出现长时间的阻塞,轻则导致系统反应变慢、界面卡顿等问题,重则会导致系统冻屏。为此Android系统设计在开机时会将一些系统框架核心工作线程加入到WatchDog的监控中,通过定期往这些线程消息循环队列中抛消息,然后检查消息是否得到及时执行来判断其是否正常顺畅运行,如果出现长时间超时得不到执行就会导致系统重启。相关简化代码如下:

/*frameworks/base/services/core/java/com/android/server/Watchdog.java*/
private Watchdog() {
        ...
        // The shared foreground thread is the main checker.  It is where we
        // will also dispatch monitor checks and do other work.
        mMonitorChecker = new HandlerChecker(FgThread.getHandler(),
                "foreground thread", DEFAULT_TIMEOUT);
        mHandlerCheckers.add(mMonitorChecker);
        // Add checker for main thread.  We only do a quick check since there
        // can be UI running on
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值