文档管理中心

应用闪退问题总结

问题现象

应用在运行过程中发生的非预期终止或无响应行为,是影响用户体验的核心痛点。主要表现为以下三种形式:

  • 闪退 (Crash):应用界面突然消失,直接返回桌面。通常由代码层面的未捕获异常引起。
  • 卡死 (Freeze):应用界面画面静止,点击无反应,随后可能弹出“应用无响应”对话框或直接退出。通常由主线程阻塞引起。
  • 非预期退出 (Process Kill):应用在后台运行或前台切换时被系统强制关闭。通常涉及系统资源管控(内存、CPU、功耗)的介入。

背景知识

定位稳定性问题,需要结合系统底层记录的“死亡现场”关键信息。主要依赖两类日志:

  1. HiLog(实时日志):用于锁定应用被终止的时间点直接原因(Reason)
  2. FaultLog(故障日志):系统自动生成的详细堆栈文件,存储在 /data/log/faultlog/faultlogger/,用于追溯具体代码行号

系统终止进程时,会抛出不同的 reason,对应的故障类型及场景如下表所示:

1. 代码崩溃类

对应日志前缀:jscrash- / cppcrash-

展开

退出 Reason

故障归因

场景深度解析

JsCrash

JS/ArkTS 崩溃

业务代码抛出未捕获异常(如空指针、类型错误、语法错误、OOMError)。

CppCrash

Native 崩溃

C/C++ 层发生非法内存访问(SIGSEGV)、断言失败(SIGABRT)或系统库异常。

2. 应用无响应类

对应日志前缀:appfreeze-

展开

退出 Reason

故障归因

场景深度解析

THREAD_BLOCK_6S

主线程卡死

主线程被锁阻塞、死循环或业务逻辑耗时过长,导致看门狗超时。

APP_INPUT_BLOCK

输入阻塞

用户点击/滑动屏幕后,主线程超过 6s 未分发处理事件。

LIFECYCLE_TIMEOUT

生命周期超时

onCreate/onForeground 等生命周期回调执行耗时过长(通常 >3-5s)。

3. 资源泄漏类

对应日志:HiLog 或 resource_leak

展开

退出 Reason

故障归因

场景深度解析

ResourceLeak:Fd Leak

The number of fd exceeds...

句柄泄漏

打开的文件、Socket、Handler 未关闭,耗尽系统 FD 资源(通常 >1024)。

ResourceLeak:Thread Leak

线程泄漏

线程只创建不销毁,数量爆炸导致 OOM 或 pthread_create 失败。

ResourceLeak:Ion Leak

图形内存泄漏

Native 层 ION 内存(DMA/图形缓冲区)申请后未释放。

ResourceLeak:Ashmem Leak

共享内存泄漏

匿名共享内存(Ashmem)耗尽,常见于跨进程大数据传输未释放。

RENDER_MEMORY_OVER_ERROR

渲染内存超限

RenderService 检测到应用占用渲染内存过大,强制管控。

ResourceLeak:Pss Soft Kill

内存软限超标

后台/低优先级清理:应用处于后台或非用户感知状态时,PSS 内存超过系统设定的“软阈值”(水位线),系统为预防 OOM 主动回收该进程。

ResourceLeak:Pss Kill

内存硬限超标

单进程内存过大:应用 PSS 内存持续增长,超过系统允许的单进程最大硬阈值(即使系统总内存充足),通常指示应用存在严重的堆内存泄漏。

4. 内存与系统管控类

对应日志:HiLog

展开

退出 Reason

故障归因

场景深度解析

LowMemoryKill

系统低内存

整机内存不足,系统按优先级回收后台应用(标准 LMK)。

SWAP_FULL

虚拟内存耗尽

系统交换分区(Swap)已满,系统被迫杀进程释放空间。

StabilityCheckKill

稳定性检测

系统检测到进程频发崩溃或状态异常,进行保护性管控。

CPU Highload

CPU 高负载

应用在后台长时间高占用 CPU(如死循环),发热严重被管控。

Power Save Clean

省电清理

超级省电模式或灭屏后,系统清理后台高耗电应用。

5. 后台与冻结管控类

*对应日志:HiLog *。

展开

退出 Reason

故障归因

场景深度解析

ContinuouslyWakeupAbnormal

异常唤醒

应用在后台频繁设置 Alarm 或持有锁,导致系统无法休眠,冻结失败后强杀。

ILLEGAL_AUDIO_RENDERER...

异常音频

应用后台挂起后仍试图播放音频,且未申请长时任务。

ILLEGAL_AUDIO_CAPTURER...

异常录音

应用后台挂起后仍试图占用麦克风,触发隐私/功耗管控。

6. 正常退出与用户行为

非故障类,属于预期内行为

展开

退出 Reason

归因分类

场景深度解析

KillApplicationSelf

应用自杀

代码主动调用 terminateSelf 或 System.exit。

User Request / Clear Session

用户杀进程

用户在最近任务列表中划掉应用,或强制停止。

UpgradeApp / UninstallApp

安装卸载

应用更新或卸载导致的进程终止。

问题定位

定位的核心逻辑遵循标准化路径:“锁定时间点 → 识别退出原因 → 提取详细堆栈 → 针对性修复”

第一步:锁定崩溃现场 (HiLog 分析)

当问题复现时,通过系统实时日志找到“死亡 Reason”是定界的第一步。

  • 前置准备:连接手机至电脑,确认应用包名(Bundle Name)。
  • 搜索指令:在 Log 工具中开启正则表达式 (Regex) 搜索:
    PROCESS_KILL.*你的包名

    (注:.* 用于匹配进程ID等中间字符,精准定位针对目标包名的杀进程动作)

  • 关键信息提取:找到形如 I ProcessManager: PROCESS_KILL: ... reason: JsCrash 的日志,记录下 reason 字段的值

第二步:获取故障堆栈 (FaultLog 提取)

根据上一步获取的 reason,导出系统生成的堆栈文件进行深度分析。

  • 存储路径:/data/log/faultlog/faultlogger/
  • 导出工具:使用终端执行 hdc file recv 命令将文件导出到本地。

分析结论

基于 PROCESS_KILL 日志中的 reason 字段,可将问题快速定界为以下几类:

  1. 代码错误类 (JsCrash / CppCrash)
    • 结论:应用自身的 JS/ArkTS 或 C++ 代码存在逻辑缺陷或非法访问。
    • 方向:需排查具体的代码行号和变量状态。
  2. 主线程阻塞类 (THREAD_BLOCK / APP_INPUT / LIFECYCLE)
    • 结论:主线程负载过重或被阻塞,导致无法及时响应用户输入或系统回调。
    • 方向:需排查主线程中的耗时操作、死锁或死循环。
  3. 系统管控类 (LowMemory / CPU Highload / RSS)
    • 结论:应用资源使用(内存、CPU)超标,或整机资源不足导致被动回收。
    • 方向:需优化应用资源占用,治理内存泄漏和后台行为。

修改建议

根据导出的 FaultLog 文件及定界结果,针对典型场景的修复策略如下:

场景 1:Reason 为 JsCrash

  • 定性:ArkTS/JS 层面的未捕获异常。
  • 分析方法:打开 jscrash- 开头的日志,搜索 Stacktrace,查找指向项目源码(Entry/Src)的文件名和行号。

场景 2:Reason 为 CppCrash

  • 定性:Native 层(NAPI/So库)的内存违规或段错误。
  • 分析方法:打开 cppcrash- 开头的日志,查看 Tid(崩溃线程)下的堆栈(#00, #01...)。
    • 若栈顶是应用自带 .so,一般路径为/data开头:应用自身 C++ 代码问题。
    • 若栈顶是系统 .so,一般路径为/system开头(如 libark_jsruntime.so):通常为上层传参错误导致系统库崩溃。

场景 3:Reason 为 APP_INPUT_BLOCK / THREAD_BLOCK_6S

  • 定性:主线程被耗时操作阻塞(ANR)。
  • 分析方法:打开 appfreeze- 日志,搜索 Name:MainThread,查看其下方的调用栈,找出重复出现或明显耗时的函数调用。

场景 4:Reason 为 LIFECYCLE_TIMEOUT

  • 定性:UIAbility 生命周期回调执行超时。
  • 分析方法:确认崩溃发生在应用启动(onCreate)或前后台切换(onForeground)阶段。
在 FAQ 中进行搜索
请输入您想要搜索的关键词