anr 分析

导出 APP  的ANR 日志

adb pull /data/anr/traces.txt ~/tmp


anr大概可以分两种,CPU 占满 或主线程 block

anr文件里有所多类似这样的开头


"main" prio=5 tid=1 Waiting


最后的一个单表示该线程的状态

ThreadState (defined at “dalvik/vm/thread.h “)

    THREAD_UNDEFINED = -1, /* makes enum compatible with int32_t */

    THREAD_ZOMBIE = 0, /* TERMINATED */

    THREAD_RUNNING = 1, /* RUNNABLE or running now */

    THREAD_TIMED_WAIT = 2, /* TIMED_WAITING in Object.wait() */

    THREAD_MONITOR = 3, /* BLOCKED on a monitor */

    THREAD_WAIT = 4, /* WAITING in Object.wait() */

    THREAD_INITIALIZING= 5, /* allocated, not yet running */

    THREAD_STARTING = 6, /* started, not yet on thread list */

    THREAD_NATIVE = 7, /* off in a JNI native method */

    THREAD_VMWAIT = 8, /* waiting on a VM resource */

    THREAD_SUSPENDED = 9, /* suspended, usually by GC or debugger */


特别说明一下MONITOR状态和SUSPEND状态,MONITOR状态一般是类的同步块或者同步方法造成的,SUSPENDED状态在debugger的时候会出现,可以用来区别是不是真的是用户正常操作跑出了ANR。


| group="main" sCount=1 dsCount=0 obj=0x415a4e88 self=0x414c48d8

group是线程组名称。sCount是此线程被挂起的次数,dsCount是线程被调试器挂起的次数,
当一个进程被调试后,sCount会重置为0,调试完毕后sCount会根据是否被正常挂起增长,但是dsCount不会被重置为0,
所以dsCount也可以用来判断这个线程是否被调试过。obj表示这个线程的Java对象的地址,self表示这个线程本身的地址。




<think>好的,我现在需要帮助用户了解如何分析Android的ANR问题。首先,我要回忆一下用户提供的引用内容,看看里面有哪些关键点需要涵盖。引用1提到要搜索am_anr,找时间点、PID、类型,然后找前5秒的日志,检查CPU信息和traces.txt。引用2指出现在不能用data/anr/traces.txt直接找,需要用adb命令。引用3说明系统生成traces.txt在/data/anr/下。引用4和5提到了CPU使用率分析,特别是关注ANR进程、system_server、kswapd0等的情况。 接下来,我需要将这些步骤整合成一个清晰的流程。首先从日志分析开始,搜索am_anr找到基本信息,然后根据PID过滤相关日志,检查CPU使用情况。接着,提取traces.txt文件,可能需要通过adb命令,因为直接访问可能过时了。然后分析堆栈信息,定位代码问题。还要注意不同进程的CPU占用情况,比如kswapd0高可能内存问题,iowait高可能I/O阻塞等。 用户可能需要一个逐步的指南,所以应该分步骤说明,每个步骤详细说明怎么做,并引用对应的参考资料。比如第一步查找ANR记录,引用15的内容;第二步获取traces.txt用adb命令,引用2和3;第三步分析CPU,引用5;第四步检查I/O或内存,引用5;第五步结合源码分析,引用1。 还要注意用户可能遇到的常见问题,比如找不到traces.txt,这时候要强调使用adb命令而不是直接查看文件。另外,需要提醒用户不同平台(高通、MTK)的日志位置可能不同,这点在引用5中提到过。 最后,生成相关问题时,要考虑用户可能进一步想知道如何预防ANR,或者具体案例,或者工具使用,如Android Studio的Profiler,这些都可以作为相关问题提出。确保回答结构清晰,步骤明确,引用正确,并且使用中文,符合用户的要求。</think>### Android ANR分析方法分步指南 --- #### **一、定位ANR记录** 1. **搜索`am_anr`日志** - 在系统日志中搜索关键字`am_anr`,获取ANR发生的时间点、进程PID、ANR类型(如输入超时、广播超时等)[^1]。 - 示例日志片段: ```logcat 07-01 10:00:00.000 E ActivityManager: ANR in com.example.app (pid 12345) ``` 2. **根据PID过滤上下文日志** - 以ANR发生时间点为基准,向前查找该PID在**前5秒内**的日志,分析主线程是否阻塞(如耗时操作、锁竞争等)。 --- #### **二、获取ANR关键文件** 1. **通过adb提取`traces.txt`** - 使用命令`adb pull /data/anr/traces.txt`导出文件(需设备已root或调试模式)[^3]。 - 若直接查看`/data/anr/traces.txt`失败,优先使用adb命令[^2]。 2. **分析`traces.txt`内容** - 查找ANR进程的堆栈信息,重点关注主线程(`main`)的状态: - 是否在等待锁(如`MONITOR`或`WAIT`)? - 是否执行耗时操作(如数据库查询、密集计算)? - 示例片段: ```java "main" prio=5 tid=1 Native | group="main" sCount=1 dsCount=0 flags=1 obj=0x74e23410 | sysTid=12345 nice=-10 cgrp=default sched=0/0 handle=0x7f8a8c4000 | state=S schedstat=( 1000000000 500000000 2000 ) utm=90 stm=10 core=0 HZ=100 | stack=0x7fc3c4a000-0x7fc3c4c000 | held mutexes= at java.lang.Object.wait(Native method) - waiting on <0x0a1b2c3d> (a java.util.concurrent.locks.ReentrantLock) ``` --- #### **三、分析CPU使用率** 1. **检查ANR前后的CPU负载** - 在日志中搜索`ANR IN`,查看CPU占用统计: - **用户态(`user`)**、**内核态(`kernel`)**、**I/O等待(`iowait`)**占比[^5]。 - 关键指标: - 若`iowait`高:可能存在磁盘I/O阻塞(如文件读写、数据库操作)。 - 若`kswapd0`进程活跃:内存不足导致频繁交换。 2. **对比进程资源占用** - 关注**ANR进程**、`system_server`、`surfaceflinger`等核心进程的CPU使用率。 - 示例日志片段: ```logcat CPU usage from 0ms to 5000ms later: 50% 12345/com.example.app: 40% user + 10% kernel 30% 678/system_server: 20% user + 10% kernel ``` --- #### **四、常见场景与解决方案** | **场景** | **分析方法** | **解决方向** | |------------------------|----------------------------------------------------------------------------|---------------------------------------| | 主线程阻塞(如数据库操作) | `traces.txt`显示主线程处于`RUNNABLE`且调用栈包含SQLite、文件IO等 | 异步线程 + 事务优化 | | 死锁 | 堆栈中多个线程显示`MONITOR`或`WAIT`,且互相持有对方需要的锁 | 检查锁顺序 + 使用超时机制 | | Binder通信超时 | `system_server`堆栈包含`Binder`调用,且ANR类型为`Broadcast`或`Service` | 优化跨进程通信耗时 + 减少数据传输量 | --- #### **五、工具辅助** 1. **Android Studio Profiler** - 实时监控主线程卡顿、内存泄漏。 2. **StrictMode** - 检测主线程中的磁盘/网络操作。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值