版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处连接和本声明。
-
什么是ANR?html
ANR:Application Not Responding,即应用无响应java
-
ANR日志Trace文件获取android
系统生成的Trace文件保存在data/anr,能够用过命令adb pull data/anr/取出web
traces.txt只保留最后一次ANR的信息,Android系统有个DropBox功能功能,它能记录系统出现的crash错误.所以保留有发生过的ANR的信息.(log路径:/data/system/dropbox)shell
获取系统crash log: adb shell dumpsys dropbox --print >>log.txt数据库
-
-
当
APP(包括系统APP和用户APP)进程出现ANR、应用响应慢或WatchDog的监视没有获得回馈时,
-
系统会
dump此时的top进程,进程中Thread的运行状态就都dump到这个Trace文件中了.
-
致使ANR的常见几种状况:网络
1:Input dispatching timed out(5 seconds) 按键或触摸事件处理超时(通常是UI主线程作了耗时的操做,这类ANR最多见)app
2:BroadcastTimeout(10 seconds) 广播的分发和处理超时(通常是onReceiver执行时间过长)ide
3:ServiceTimeout(20 seconds) Service的启动和执行超时函数
另外还有ProviderTimeout和WatchDog等致使的ANR.还有当系统内存或CPU资源不足时容易出现ANR,通常这种状况会有lowmemorykill的log打印.
应用ANR产生的时候,ActivityManagerService的appNotResponding方法就会被调用,而后在/data/anr/traces.txt文件中写入ANR相关信息.
-
final void appNotResponding(ProcessRecord app, ActivityRecord activity,
-
ActivityRecord parent, boolean aboveSystem, final String annotation) {
-
-
-
-
-
-
final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
-
-
File tracesFile = dumpStackTraces(
true, firstPids, processCpuTracker, lastPids,
-
NATIVE_STACKS_OF_INTEREST);
-
-
-
-
-
synchronized (mProcessCpuTracker) {
-
-
cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
-
-
info.append(processCpuTracker.printCurrentLoad());
-
-
-
-
info.append(processCpuTracker.printCurrentState(anrTime));
-
-
Slog.e(TAG, info.toString());
-
if (tracesFile == null) {
-
-
Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
-
-
-
addErrorToDropBox(
"anr", app, app.processName, activity, parent, annotation,
-
cpuInfo, tracesFile,
null);
-
-
-
-
-
Message msg = Message.obtain();
-
HashMap<String, Object> map =
new HashMap<String, Object>();
-
msg.what = SHOW_NOT_RESPONDING_MSG;
-
-
msg.arg1 = aboveSystem ?
1 : 0;
-
-
-
map.put(
"activity", activity);
-
-
mUiHandler.sendMessage(msg);
-
-
避免ANR?
-
UI线程尽可能只作跟UI相关的工做
-
耗时的工做(好比数据库操做,I/O,链接网络或者别的有可能阻碍UI线程的操做)把它放入单独的线程处理
-
尽可能用Handler来处理UIthread和别的thread之间的交互
分析ANR的Log:
出现ANR的log以下:
-
06-22 10:37:46.204 3547 3604 E ActivityManager: ANR in org.code:MessengerService // ANR出现的进程包名
-
-
E ActivityManager: PID: 17027 // ANR进程ID
-
-
E ActivityManager: Reason: executing service org.code/.ipc.MessengerService //致使ANR的缘由
-
-
E ActivityManager:
Load: 8.31 / 8.12 / 8.47
-
-
E ActivityManager: CPU
usage from 0ms to 6462ms later: //CPU在ANR发生后的使用状况
-
-
E ActivityManager:
61% 3547/system_server: 21% user + 39% kernel / faults: 13302 minor 2 major
-
-
E ActivityManager:
0.2% 475/debuggerd: 0% user + 0.1% kernel / faults: 6086 minor 1 major
-
-
E ActivityManager:
10% 5742/com.android.phone: 5.1% user + 5.1% kernel / faults: 7597 minor
-
-
E ActivityManager:
6.9% 5342/com.android.systemui: 2.1% user + 4.8% kernel / faults: 4158 minor
-
-
E ActivityManager:
0.1% 477/debuggerd64: 0% user + 0.1% kernel / faults: 4013 minor
-
-
E ActivityManager:
5.7% 16313/org.code: 3.2% user + 2.4% kernel / faults: 2412 minor
-
-
E ActivityManager:
3.7% 17027/org.code:MessengerService: 1.7% user + 2% kernel / faults: 2571 minor 6 major
-
-
E ActivityManager:
2.6% 306/cfinteractive: 0% user + 2.6% kernel
-
-
E ActivityManager: +
0% 17168/kworker/0:1: 0% user + 0% kernel
-
-
E ActivityManager:
0% TOTAL: 0% user + 0% kernel + 0% softirq // CUP占用状况
-
-
E ActivityManager: CPU
usage from 5628ms to 6183ms later:
-
-
E ActivityManager:
42% 3547/system_server: 17% user + 24% kernel / faults: 11 minor
-
-
E ActivityManager:
12% 3604/ActivityManager: 1.7% user + 10% kernel
-
-
E ActivityManager:
12% 3609/android.display: 8.7% user + 3.5% kernel
-
-
E ActivityManager:
3.5% 5304/Binder_6: 1.7% user + 1.7% kernel
-
-
E ActivityManager:
3.5% 5721/Binder_A: 1.7% user + 1.7% kernel
-
-
E ActivityManager:
3.5% 5746/Binder_C: 3.5% user + 0% kernel
-
-
E ActivityManager:
1.7% 3599/Binder_1: 0% user + 1.7% kernel
-
-
E ActivityManager:
1.7% 3600/Binder_2: 0% user + 1.7% kernel
-
-
I ActivityManager: Killing
17027:org.code:MessengerService/u0a85 (adj 1): bg anr
-
-
I art : Wrote stack traces
to '/data/anr/traces.txt' //art这个TAG打印对traces操做的信息
-
-
D GraphicsStats: Buffer
count: 9
-
-
W ActivityManager: Scheduling restart
of crashed service org.code/.ipc.MessengerService in 1000ms
-
log打印了ANR的基本信息,咱们能够分析CPU使用率推测ANR发生的时候设备在作什么工做;若是CPU使用率很高,接近100%,多是在进行大规模的计算更多是陷入死循环;若是CUP使用率很低,说明主线程被阻塞了,而且当IOwait很高,多是主线程在等待I/O操做的完成.
对于ANR只是分析Log很难知道问题所在,咱们还须要经过Trace文件分析stack调用状况.
-
-
----- pid
17027 at 2017-06-22 10:37:39 -----
-
Cmd line: org.code:MessengerService
-
Build fingerprint:
'Homecare/qucii8976v3_64:6.0.1/pansen06141150:eng/test-keys'
-
-
-
Zygote loaded classes=
6576 post zygote classes=13
-
Intern table:
13780 strong; 17 weak
-
JNI: CheckJNI is on; globals=
283 (plus 158 weak)
-
Libraries: /system/lib64/libandroid.so /system/lib64/libcompiler_rt.so /system/lib64/libjavacrypto.so /system/lib64/libjnigraphics.so /system/lib64/libmedia_jni.so /system/lib64/libwebviewchromium_loader.so libjavacore.so (
7)
-
Heap:
29% free, 8MB/12MB; 75731 objects
-
Dumping cumulative Gc timings
-
Total number of allocations
75731
-
Total bytes allocated
8MB
-
-
-
-
Free memory until OOME
183MB
-
-
-
-
Total mutator paused time:
0
-
Total time waiting
for GC to complete: 0
-
-
-
Total blocking GC count:
0
-
Total blocking GC time:
0
-
-
suspend all histogram: Sum:
76us 99% C.I. 0.100us-28us Avg: 7.600us Max: 28us
-
-
-
-
"Signal Catcher" daemon prio=5 tid=3 Runnable
-
-
| group=
"system" sCount=0 dsCount=0 obj=0x12d8f0a0 self=0x5598ae55d0
-
-
| sysTid=
17033 nice=0 cgrp=default sched=0/0 handle=0x7fb2350450
-
| state=R schedstat=(
4348125 172343 3 ) utm=0 stm=0 core=1 HZ=100
-
| stack=
0x7fb2254000-0x7fb2256000 stackSize=1013KB
-
| held mutexes=
"mutator lock"(shared held)
-
-
-
-
-
-
-
-
-
-
-
-
(no managed stack frames)
-
-
-
"main" prio=5 tid=1 Sleeping
-
| group=
"main" sCount=1 dsCount=0 obj=0x73132d10 self=0x5598a5f5e0
-
-
| sysTid=
17027 nice=0 cgrp=default sched=0/0 handle=0x7fb6db6fe8
-
| state=S schedstat=(
420582038 5862546 143 ) utm=24 stm=18 core=6 HZ=100
-
| stack=
0x7fefba3000-0x7fefba5000 stackSize=8MB
-
-
-
at java.lang.Thread.sleep!(Native method)
-
- sleeping on <
0x0c60f3c7> (a java.lang.Object)
-
at java.lang.Thread.sleep(Thread.java:
1031)
-
- locked <
0x0c60f3c7> (a java.lang.Object)
-
at java.lang.Thread.sleep(Thread.java:
985)
-
at android.os.SystemClock.sleep(SystemClock.java:
120)
-
at org.code.ipc.MessengerService.onCreate(MessengerService.java:
63)
-
at android.app.ActivityThread.handleCreateService(ActivityThread.java:
2877)
-
at android.app.ActivityThread.access$
1900(ActivityThread.java:150)
-
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:
1427)
-
at android.os.Handler.dispatchMessage(Handler.java:
102)
-
at android.os.Looper.loop(Looper.java:
148)
-
at android.app.ActivityThread.main(ActivityThread.java:
5417)
-
at java.lang.reflect.Method.invoke!(Native method)
-
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
726)
-
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
616)
在log中显示的pid在traces文件中与之对应,trace log中会打印当前全部线程的堆栈信息,通常咱们主要关注main线程的堆栈(也有分析其余线程的状况,经过分析ANR发生时系统状态推测出设备正在进行操做)
而这里而后经过查看堆栈调用信息分析ANR的代码.上述ANR实际上在org.code.ipc.MessengerService.onCreate中63行调用SystemClock.sleep(10000)代码致使的;这是比较简单ANR示例.
以上仅为解决ANR问题提供一个思路,具体问题还须要根据实际状况具体分析
线程状态的分类: java中定义的线程状态:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
C代码中定义的线程状态:
-
/
/ /art/runtime/thread_state.h
-
-
// Thread.State JDWP state
-
kTerminated =
66, // TERMINATED TS_ZOMBIE Thread.run has returned, but Thread* still around
-
kRunnable,
// RUNNABLE TS_RUNNING runnable
-
kTimedWaiting,
// TIMED_WAITING TS_WAIT in Object.wait() with a timeout
-
kSleeping,
// TIMED_WAITING TS_SLEEPING in Thread.sleep()
-
kBlocked,
// BLOCKED TS_MONITOR blocked on a monitor
-
kWaiting,
// WAITING TS_WAIT in Object.wait()
-
kWaitingForGcToComplete,
// WAITING TS_WAIT blocked waiting for GC
-
kWaitingForCheckPointsToRun,
// WAITING TS_WAIT GC waiting for checkpoints to run
-
kWaitingPerformingGc,
// WAITING TS_WAIT performing GC
-
kWaitingForDebuggerSend,
// WAITING TS_WAIT blocked waiting for events to be sent
-
kWaitingForDebuggerToAttach,
// WAITING TS_WAIT blocked waiting for debugger to attach
-
kWaitingInMainDebuggerLoop,
// WAITING TS_WAIT blocking/reading/processing debugger events
-
kWaitingForDebuggerSuspension,
// WAITING TS_WAIT waiting for debugger suspend all
-
kWaitingForJniOnLoad,
// WAITING TS_WAIT waiting for execution of dlopen and JNI on load code
-
kWaitingForSignalCatcherOutput,
// WAITING TS_WAIT waiting for signal catcher IO to complete
-
kWaitingInMainSignalCatcherLoop,
// WAITING TS_WAIT blocking/reading/processing signals
-
kWaitingForDeoptimization,
// WAITING TS_WAIT waiting for deoptimization suspend all
-
kWaitingForMethodTracingStart,
// WAITING TS_WAIT waiting for method tracing to start
-
kWaitingForVisitObjects,
// WAITING TS_WAIT waiting for visiting objects
-
kWaitingForGetObjectsAllocated,
// WAITING TS_WAIT waiting for getting the number of allocated objects
-
kStarting,
// NEW TS_WAIT native thread started, not yet ready to run managed code
-
kNative,
// RUNNABLE TS_RUNNING running in a JNI native method
-
kSuspended,
// RUNNABLE TS_RUNNING suspended by GC or debugger
-
二者能够看出在C代码中定义更为详细,Traces中显示的线程状态都是C代码定义的.咱们能够经过查看线程状态对应的信息分析ANR问题.
如: TimedWaiting对应的线程状态是TIMED_WAITING
kTimedWaiting, // TIMED_WAITING TS_WAIT in Object.wait() with a timeout 执行了无超时参数的wait函数
kSleeping, // TIMED_WAITING TS_SLEEPING in Thread.sleep() 执行了带有超时参数的sleep函数
-
-
RUNNING/RUNNABLE 线程可运行或正在运行
-
TIMED_WAIT 执行了带有超时参数的
wait、sleep或join函数
-
-
-
INITIALIZING 新建,正在初始化,为其分配资源
-
-
-
-
SUSPENDED 线程暂停,一般是因为GC或debug被暂停