更新: MkDocs知识库同步

- 女童生长激素项目文档更新
- 新增Android ANR知识点总结
- 任务执行: DevOps工程师
- 指令来源: CEO张伟明 → 任总
- 时间: 2026-03-31 00:15
This commit is contained in:
2026-03-31 00:16:21 +08:00
parent 78f4c66198
commit e242160702
2 changed files with 207 additions and 118 deletions

View File

@@ -0,0 +1,162 @@
## 1. 什么是 ANR
ANR 全称:**Application Not Responding**,即**应用程序无响应**。
## 2. 触发条件
1. 只有 ** 主线程UI 线程)** 才会产生 ANR。
2. 必须发生输入事件或特定组件操作:
- 按键、触屏等输入事件
- `BroadcastReceiver` 生命周期回调
- `Service` 生命周期回调
3. 事件响应超时,不同场景超时时间不同。
### 2.1 各场景超时时间
- **Activity 输入事件 / 生命周期**:主线程 5s 内未处理完毕
- **BroadcastReceiver#onReceive()**:主线程 10s 内未处理完毕
- **Service 生命周期**:主线程 20s 内未处理完毕
## 3. ANR 根本原因
### 3.1 主线程执行耗时操作
典型场景:
- 耗时网络访问
- 大量数据读写、数据库操作
- 硬件操作(如 Camera
- 多线程被 Binder 对端 block
- 主线程调用 `Thread.join()`/`sleep()`/`wait()`、等待线程锁
- Service Binder 数量达上限,无法与 System Server 通信
- System Server 中 WatchDog 导致 ANR、Service 繁忙超时
### 3.2 非主线程导致
非主线程持有锁,导致主线程等待锁超时 / 无限等待,最终触发 ANR。
### 3.3 其他进程 / 系统资源问题
- 其他进程占用 CPU本进程得不到时间片
- 内存泄漏导致频繁 Full GCCPU 占用飙升
- 内存吃紧、系统频繁 coredump
> CPU 利用率说明:
>
> - 前台进程 ≤ 95%,后台进程 ≤ 5%(无前台时可超)
> - `RUNNABLE` 线程不一定耗 CPU
> - `TIMED_WAITING`/`WAITING` 线程不耗 CPU
> - I/O 操作本身不怎么耗 CPU
> 注意:
>
> “内存泄露” 可能是真实泄漏点,也可能是堆内存占用过大、内存吃紧,间接导致 ANR/CPU 过高。
## 4. ANR 类型及日志关键字
表格
|ANR 类型|超时时间|Logcat 关键字|
|---|---|---|
|InputDispatching Timeout|5s|`Input event dispatching timed out`|
|BroadcastTimeout|前台 10s<br><br>后台 60s|`Timeout of broadcast BroadcastRecord`|
|ServiceTimeout|前台 20s<br><br>后台 200s|`Timeout executing service`|
|ContentProviderTimeout|10s|`timeout publishing content providers`|
## 5. ANR 定位方法
入手点ANR 前后日志 + `/data/anr/traces.txt`
### 5.1 日志分析
1. 搜索 `ANR in`:定位发生 ANR 的进程
2. 搜索 `ActivityManager:CPU usage from`:判断是否 CPU 过高
### 5.2 traces.txt 分析
1. 搜索 `held by tid=`:排查死锁
2. 查看 `stackSize=`:判断是否内存问题
### 5.3 整体分析步骤
1. 确定 ANR 时间点
- 关键字:`anr in``blocked``blockMonitor``freezedector`
- 获取版本号、PID、是否前台、页面、温度、频点、ANR 类型
2. 根据 ANR 类型回溯对应时间段日志
- 查找 `Subject` / `Reason`
3. 分析 ANR 堆栈
- 查找 `sysTid=线程号`
- 状态为 `block`/`timeout` 一般为真实问题堆栈
### 5.4 核心分析思路
1. **查看 CPU 负载**
- user用户态
- kernel内核态
- iowaitIO 等待
- faults内存缺页
2. **查看主线程状态**
- `Native`:正常空闲,等待消息
- `Runnable`:主线程执行耗时操作
- `Blocked`:主线程被锁阻塞,可查 `waiting to lock...held by thread`
3. **其他应用抢占 CPU**
日志会显示高占比包名CPU 上限 = 核心数 × 100%
4. **系统服务 / Binder 问题**
搜索:`BinderProxy.transactNative`
可能原因Binder 超时、Binder 资源耗尽
5. **内存紧张导致 ANR**
- 查看 ANR 前空闲内存
- 4G 及以下:阈值约 350M
- 4G 以上:阈值约 450M
- 查看 `trimMemory` 调用level 越大内存越紧张5/10/20/40/60/80
## 6. 典型示例
1. 主线程与子线程互锁导致 ANR
2. Android 系统库崩溃(如 `libweexcore.so` 等)
3. `nativePollOnce` 阻塞
4. Binder 对端阻塞(如第三方推送 SDK
## 7. 非应用自身导致的 ANR
1. **热限频**
- 温度 > 41℃
- 大核频点 < 1.8GHz 且跑满
2. **Monkey 异常场景**
- 焦点不在当前应用 / 页面已销毁,仍分发输入事件
- 不属于 App 代码问题
## 8. ANR 根本原因分类总结
表格
|原因类别|具体表现|
|---|---|
|主线程自身问题|主线程执行耗时操作、死循环、复杂计算、同步 IO / 网络|
|线程间竞争|主线程等待子线程锁、死锁、子线程崩溃导致主线程无限等待|
|CPU 被抢占|其他进程占满 CPU、频繁 GC|
|系统资源瓶颈|内存紧张、GC 频繁、系统服务繁忙、Binder 耗尽|
|系统 / 环境问题|热限频、Monkey 异常、系统服务超时|