开发态快速定位Freeze

0 评论 219 浏览 0 收藏 10 分钟

本原创文章帖发布在华为开发者联盟社区,欢迎开发者前往访问评论交流,更多与该内容相关讨论,请点击原帖查看:

开发态快速定位Freeze-华为开发者话题 | 华为开发者联盟

1.1 AppFreeze屏分析流程与高频场景

当应用发生冻屏时,用户通常会遇到以下现象:

       1. 界面无响应:应用界面点击无效、画面静止、无法响应用户操作(如滑动、点击按钮等)。

       2. 系统弹窗提示:持续一段时间(通常为3-6秒)后,系统可能弹出“应用未响应”对话框,提示用户等待或关闭应用。

       3. 应用闪退或强制终止若冻屏状态持续,系统为保障整体流畅度,可能会强制终止该应用进程,导致应用闪退。

       4. 日志特征:在系统或应用日志中会出现特定的故障类型关键字,如 THREAD_BLOCK_6S(应用主线程冻屏超时)、APP_INPUT_BLOCK(用户输入响应超时)。

1.1.1 THREAD_BLOCK_6S(应用主线程冻屏超时)

THREAD_BLOCK_6S (应用主线程冻屏超时)

触发条件

           • 如果判活检测任务超过3未被主线程执行,系统会上报 THREAD_BLOCK_3S警告事件,并抓取一次瞬时堆栈(Warning)。

           • 如果判活检测任务超过6仍未被主线程执行,系统则判定主线程已冻屏,上报 THREAD_BLOCK_6S主线程冻屏事件,并抓取最终堆栈(Error)。

           • 两个事件匹配后,系统会生成完整的应用冻屏日志,并通常会导致应用被强制终止。

           • 根本原因:这表明应用主线程被长时间阻塞,无法处理新任务。常见原因包括:在主线程执行耗时计算、同步网络请求、大文件IO、复杂UI渲染、死锁、或消息队列因高优先级任务过多导致watchdog任务无法被及时调度等。

1.1.2 APP_INPUT_BLOCK(用户输入响应超时

APP_INPUT_BLOCK (用户输入响应超时)

           • 触发条件:如果应用侧的回执超时,系统即判定为用户输入响应超时,上报 APP_INPUT_BLOCK故障。

           • 根本原因:由于主线程繁忙或阻塞,无法及时处理输入事件所致。

1.2 标准化排查流程

冻屏检测会生成故障日志,其中包含冻屏堆栈(3s warning栈和6s error栈)。

1. 获取冻屏日志

通过DevEco Studio的底部FaultLog模块或触发冻屏现象时DevEco Studio右下提示框直接跳转至FaultLog。

2. 查看信息分析故障类型

进入Fault Analysis页签查看Freeze type

           • THREAD_BLOCK_6S:应用主线程冻屏超时(前台6秒,后台21秒)。

           • APP_INPUT_BLOCK:用户输入响应超时。

       3. 解析堆栈信息

查看3s/6s Compare

       对比3秒(warning)和6秒(error)的堆栈,对非THREAD_BLOCK_6S类型的App冻屏问题,则分析消息队列。

       根据3s/6s堆栈一致则推断是主线程阻塞,不一致则主线程繁忙;

4. 分析主线程堆栈

查看Sampling Stack定位到故障指向,结合指向的业务路径和系统负载信息推断导致主线程繁忙/阻塞的业务代码逻辑并优化修复。

1.2.1 冻屏分析案例

案例背景

 用户在操作应用时(如点击按钮、滑动屏幕、按键),应用界面完全无反应,仿佛“冻结”了一般。持续等待约5秒后,应用进程被系统终止或弹出“应用无响应”提示框。

1.2.2 分析流程

1.2.2.1 配置获取App冻屏增强日志

查看采样栈数据之前,需要在AppScope/app.json5文件中配置如下环境变量,获取App冻屏增强日志。

"appEnvironments": [
{
  "name": "DFX_APPFREEZE_LOG_OPTIONS",
  "value": "mainthread_sampling:enable"
}
]

1.2.2.2 查看FaultLog

打开FaultLog窗口,双击app冻屏日志,查看faultlog头部的Event、Timestamp及Reason字段可以初步定位场景

1.2.2.3 查看Fault Analysis

 Fault Info右侧会出现Fault Analysis页签,点击Fault Analysis页签,会展示结构化的日志信息。

       查看Freeze type 确认场景为THREAD_BLOCK_6S(主线程卡死超时)

 对比3秒(warning)和6秒(error)的堆栈:

           • 3秒和6秒的栈不一致:说明线程仍在执行业务代码,可能是任务过重导致主线程繁忙,需结合采样栈进一步确认。

1.2.2.4 分析Sampling Stack

步骤4:分析Sampling Stack

 Sampling Stack页签展示应用堆栈(绿色标识)和系统堆栈(蓝色标识)

点击切换图表类型按钮,可切换到堆栈火焰图,并通过不同颜色标识堆栈类型,其中红色代表异常堆栈,图中异常堆栈指向业务page,结合前面步骤3s/6s堆栈不一致的场景,此时需要定位page中导致主线程繁忙的业务逻辑。

进入对应业务代码查看发现存在两处严重导致主线程业务繁忙的问题。

       1. 这是一个空循环,在主线程上持续运行 3秒,循环体内没有任何操作,纯粹占用CPU资源,在此期间,主线程完全被阻塞,无法响应任何UI事件、触摸输入或渲染更新。

       2. 超大规模的同步I/O操作

1.2.2.5 优化修复

优化修复

 1. 移除忙等待循环

       2. 使用异步API替代同步API

       3. 根据实际需求设置合理的循环次数

1.3 附录 :常见修复建议

根据问题特征,冻屏根因可分为以下几类:

       1. 应用代码问题:如执行耗时函数、内存泄漏导致频繁GC、高优先级任务过多。优化方法包括将耗时操作移至子线程、减少内存泄漏、合理控制任务优先级。

       2. 死锁问题:堆栈显示持锁等待。需检查代码中的锁使用,避免循环等待。

       3. 调度问题:trace显示主线程长时间runnable。需调整任务优先级或联系调度域协助。

       4. 系统库或IO问题:堆栈卡在系统库调用或IO操作。需排查系统库接口的耗时或IO阻塞情况。

本文由 @华为开发者联盟 授权发布于人人都是产品经理。未经作者许可,禁止转载

题图来自Unsplash,基于CC0协议

该文观点仅代表作者本人,人人都是产品经理平台仅提供信息存储空间服务

更多精彩内容,请关注人人都是产品经理微信公众号或下载App
评论
评论请登录
  1. 目前还没评论,等你发挥!