ANR分析

产生ANR的原因

  • While your activity is in the foreground, your app has not responded to an input event or BroadcastReceiver (such as key press or screen touch events) within 5 seconds.
  • While you do not have an activity in the foreground, your BroadcastReceiver hasn’t finished executing within a considerable amount of time.

分析日志

traces文件位置

04-14 15:38:51.772 1967-1976/? I/art: Wrote stack traces to '/data/anr/traces.txt'

使用adb pull /data/anr/traces.txt E:\命令就能导出traces文件到pc.

有些设备会根据触发anr的程序包名和时间对traces文件进行重命名,上述方法就取不到traces文件了。就需要用到adb shell命令了:

adb shell //进入 adb shell
cat /data/anr/traces-xxx.txt > /mnt/sdcard/traces.txt //将 traces文件从 anr目录中导出到 sdcard中。
exit //退出 adb shell
adb pull /mnt/sdcard/traces.txt C:\traces.txt //将 sdcard中的 traces文件导出到pc中。

CPU消耗

出现ANR后,系统会给出CPU的使用情况

04-14 15:38:51.772 1967-1976/? I/art: Wrote stack traces to '/data/anr/traces.txt'
04-14 15:38:51.775 1580-1671/? E/ActivityManager: ANR in com.xiaoyusan.android (com.xiaoyusan.android/.MainActivity)
                                                  PID: 30825
                                                  Reason: Input dispatching timed out (com.xiaoyusan.android/com.xiaoyusan.android.MainActivity, Waiting to send non-key event because the touched window has not finished processing certain input events that were delivered to it over 500.0ms ago.  Wait queue length: 21.  Wait queue head age: 17811.4ms.)
                                                  Load: 8.14 / 7.13 / 7.13
                                                  CPU usage from 12232ms to 0ms ago (2018-04-14 15:38:36.425 to 2018-04-14 15:38:48.657):
                                                    98% 30825/com.xiaoyusan.android: 97% user + 1.4% kernel / faults: 890 minor 98 major
                                                    23% 1580/system_server: 14% user + 9.2% kernel / faults: 7731 minor 778 major
                                                    4.7% 1967/com.android.systemui: 3.2% user + 1.4% kernel / faults: 4035 minor 87 major
                                                    4.1% 572/surfaceflinger: 2% user + 2.1% kernel / faults: 326 minor
                          ....                         
                                                    0% 740/jbd2/dm-1-8: 0% user + 0% 

从12232ms前到0ms前CPU的平均负载:

CPU usage from 12232ms to 0ms ago (2018-04-14 15:38:36.425 to 2018-04-14 15:38:48.657):

com.xiaoyusan.android进程消耗了98%的CPU, 说明这个进程内可能存在耗时操作,并且堵塞了主线程:

98% 30825/com.xiaoyusan.android: 97% user + 1.4% kernel / faults: 890 minor 98 major

然后会打印anr traces, 显示是进程id为20401的com.xiaoyusan.android进程出了问题。

procrank:
// Exception from procrank:
java.io.IOException: Cannot run program "procrank": error=13, Permission denied
anr traces:

----- pid 30401 at 2018-04-09 15:54:05 -----
Cmd line: com.xiaoyusan.android
Build fingerprint: 'xiaomi/tiffany/tiffany:7.1.2/N2G47H/V9.0.3.0.NDBCNEI:user/release-keys'
ABI: 'arm'
Build type: optimized
Zygote loaded classes=4571 post zygote classes=2561
Intern table: 47411 strong; 1381 weak
JNI: CheckJNI is on; globals=770 (plus 543 weak)
Libraries: /data/app/com.xiaoyusan.android-1/lib/arm/libBugly.so /data/app/com.xiaoyusan.android-1/lib/arm/libjpush217.so /data/app/com.xiaoyusan.android-1/lib/arm/libweibosdkcore.so /data/user/0/com.xiaoyusan.android/app_tbs/core_share/liblinuxtoolsfortbssdk_jni.so /data/user/0/com.xiaoyusan.android/app_tbs/core_share/libtbs_crash_handler.so /data/user/0/com.xiaoyusan.android/app_tbs/core_share/libwebp_base.so /system/app/WebViewGoogle/WebViewGoogle.apk!/lib/armeabi-v7a/libwebviewchromium.so /system/lib/libandroid.so /system/lib/libcompiler_rt.so /system/lib/libjavacrypto.so /system/lib/libjnigraphics.so /system/lib/libmedia_jni.so /system/lib/libmiuiclassproxy.so /system/lib/libmiuinative.so /system/lib/libsechook.so /system/lib/libwebviewchromium_loader.so /system/lib/libwebviewchromium_plat_support.so /vendor/lib/libqti_performance.so libjavacore.so libopenjdk.so (20)
/data/user/0/com.xiaoyusan.android/app_tbs/core_unzip_tmp/TencentLocationSDK.dex: speed
/data/user/0/com.xiaoyusan.android/app_tbs/core_unzip_tmp/tbs_sdk_extension_dex.dex: speed
/data/user/0/com.xiaoyusan.android/app_tbs/core_unzip_tmp/fullscreen_player_dex.dex: speed
/data/user/0/com.xiaoyusan.android/app_tbs/core_unzip_tmp/qziper_dex.dex: speed
/data/user/0/com.xiaoyusan.android/app_tbs/core_unzip_tmp/game_impl_dex.dex: speed
/data/user/0/com.xiaoyusan.android/app_tbs/core_unzip_tmp/tbs_bugly_dex.dex: speed
/data/user/0/com.xiaoyusan.android/app_tbs/core_unzip_tmp/video_impl_dex.dex: speed
/data/user/0/com.xiaoyusan.android/app_tbs/core_share/tbs_sdk_extension_dex.dex: speed
/data/user/0/com.xiaoyusan.android/app_tbs/core_unzip_tmp/tbs_game_sandbox_dex.dex: speed
/data/user/0/com.xiaoyusan.android/app_tbs/core_unzip_tmp/tbs_jars_fusion_dex.dex: speed
/data/user/0/com.xiaoyusan.android/app_tbs/core_unzip_tmp/miniqb_dex.dex: speed
/data/user/0/com.xiaoyusan.android/app_tbs/core_share/tbs_jars_fusion_dex.dex: speed
/system/framework/oat/arm/QPerformance.odex: speed
/data/app/com.xiaoyusan.android-1/oat/arm/base.odex: interpret-only
/system/framework/oat/arm/volley.odex: speed
/system/app/WebViewGoogle/oat/arm/WebViewGoogle.odex: speed
Current JIT code cache size: 78KB
Current JIT data cache size: 99KB
Current JIT capacity: 256KB
...

suspend all histogram:  Sum: 559us 99% C.I. 3us-115us Avg: 37.266us Max: 115us
DALVIK THREADS (63):
"Thread-92" prio=5 tid=62 Runnable
  | group="main" sCount=0 dsCount=0 obj=0x13cfadc0 self=0xc3c10d00
  | sysTid=30854 nice=0 cgrp=default sched=0/0 handle=0xbb0fa920
  | state=R schedstat=( 14519271 15400417 53 ) utm=0 stm=1 core=3 HZ=100
  | stack=0xbaff8000-0xbaffa000 stackSize=1038KB
  | held mutexes= "mutator lock"(shared held)
  at java.lang.reflect.Array.newInstance(Array.java:109)
  at com.tencent.smtt.sdk.a.a.a(unavailable:-1)
  at com.tencent.smtt.sdk.a.a.a(unavailable:-1)
  at com.tencent.smtt.sdk.a.a.b(unavailable:-1)
  at com.tencent.smtt.sdk.a.a.a(unavailable:-1)
  at com.tencent.smtt.utils.q.a(unavailable:-1)
  at com.tencent.smtt.utils.n.a(unavailable:-1)
  at com.tencent.smtt.sdk.TbsLogReport.b(unavailable:-1)
  - locked <0x0ce7c7b9> (a com.tencent.smtt.sdk.TbsLogReport)
  at com.tencent.smtt.sdk.ar.run(unavailable:-1)
  at java.lang.Thread.run(Thread.java:760)

"Thread-Pool-IoBound-1" prio=5 tid=33 Runnable
  | group="main" sCount=0 dsCount=0 obj=0x13be4310 self=0xc3a8a400
  | sysTid=30848 nice=11 cgrp=bg_non_interactive sched=0/0 handle=0xc17f7920
  | state=R schedstat=( 39091150 38627085 109 ) utm=3 stm=0 core=4 HZ=100
  | stack=0xc16f5000-0xc16f7000 stackSize=1038KB
  | held mutexes= "mutator lock"(shared held)
  native: #00 pc 00351041  /system/lib/libart.so (_ZN3art15DumpNativeStackERNSt3__113basic_ostreamIcNS0_11char_traitsIcEEEEiP12BacktraceMapPKcPNS_9ArtMethodEPv+128)
  native: #01 pc 00331799  /system/lib/libart.so (_ZNK3art6Thread9DumpStackERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEEbP12BacktraceMap+308)
  native: #02 pc 003437ad  /system/lib/libart.so (_ZN3art14DumpCheckpoint3RunEPNS_6ThreadE+620)
  native: #03 pc 0033231f  /system/lib/libart.so (_ZN3art6Thread21RunCheckpointFunctionEv+146)
  native: #04 pc 003f4009  /system/lib/libart.so (_ZN3artL12GoToRunnableEPNS_6ThreadE+52)
  native: #05 pc 003f4329  /system/lib/libart.so (_ZN3art25JniMethodEndWithReferenceEP8_jobjectjPNS_6ThreadE+12)
  native: #06 pc 0000ca87 
  ...

打印的第一个线程很可能是出问题的线程:

suspend all histogram:  Sum: 559us 99% C.I. 3us-115us Avg: 37.266us Max: 115us
DALVIK THREADS (63):
"Thread-92" prio=5 tid=62 Runnable
  | group="main" sCount=0 dsCount=0 obj=0x13cfadc0 self=0xc3c10d00
  | sysTid=30854 nice=0 cgrp=default sched=0/0 handle=0xbb0fa920
  | state=R schedstat=( 14519271 15400417 53 ) utm=0 stm=1 core=3 HZ=100
  | stack=0xbaff8000-0xbaffa000 stackSize=1038KB
  | held mutexes= "mutator lock"(shared held)
  at java.lang.reflect.Array.newInstance(Array.java:109)
  at com.tencent.smtt.sdk.a.a.a(unavailable:-1)
  at com.tencent.smtt.sdk.a.a.a(unavailable:-1)
  at com.tencent.smtt.sdk.a.a.b(unavailable:-1)
  at com.tencent.smtt.sdk.a.a.a(unavailable:-1)
  at com.tencent.smtt.utils.q.a(unavailable:-1)
  at com.tencent.smtt.utils.n.a(unavailable:-1)
  at com.tencent.smtt.sdk.TbsLogReport.b(unavailable:-1)
  - locked <0x0ce7c7b9> (a com.tencent.smtt.sdk.TbsLogReport)
  at com.tencent.smtt.sdk.ar.run(unavailable:-1)
  at java.lang.Thread.run(Thread.java:760)
 ```

 `- locked`代表`TbsLogReport#b()`方法中持有`TbsLogReport`对象`a`的锁,也就是存在`Synchronized(TbsLogReport.this)`语句。

 ```
 at com.tencent.smtt.sdk.TbsLogReport.b(unavailable:-1)
  - locked <0x0ce7c7b9> (a com.tencent.smtt.sdk.TbsLogReport)

那就很可能是子线程和主线程都锁住了同一个对象,然后子线程耗时,导致主线程获取不到锁,进而导致ANR. 例如:

@Override
public void onClick(View v) {
    // The worker thread holds a lock on lockedResource
   new LockTask().execute(data);

   synchronized (lockedResource) {
       // The main thread requires lockedResource here
       // but it has to wait until LockTask finishes using it.
   }
}

public class LockTask extends AsyncTask<Integer[], Integer, Long> {
   @Override
   protected Long doInBackground(Integer[]... params) {
       synchronized (lockedResource) {
           // This is a long-running operation, which makes
           // the lock last for a long time
           BubbleSort.sort(params[0]);
       }
   }
}

注意:经过测试,假设两个线程分别含有Synchronized(TbsLogReport.this)Synchronized(TbsLogReport.class)锁,那么这两个线程都要等对方释放,才能获取到锁。

“main”代表主线程,Blocked是线程状态,代表主线程被阻塞,就是上述子线程中的锁没有释放,导致主线程被锁住,引发ANR.

"main" prio=5 tid=1 Blocked
  | group="main" sCount=1 dsCount=0 obj=0x75d48000 self=0xec405400
  | sysTid=10945 nice=-4 cgrp=default sched=0/0 handle=0xef082538
  | state=S schedstat=( 2441995099 1350925397 6738 ) utm=199 stm=45 core=1 HZ=100
  | stack=0xff18a000-0xff18c000 stackSize=8MB
  | held mutexes=
  at android.app.Activity.setResult(Activity.java:5131)
  - waiting to lock <0x09a63986> (a com.xiaoyusan.android.MainActivity) held by thread 66
  at com.xiaoyusan.android.api.NavigationApi.back(NavigationApi.java:85)
  at com.xiaoyusan.android.page.HomePage.onBackPressed(HomePage.java:115)
  at com.xiaoyusan.android.MainActivity.onBackPressed(MainActivity.java:161)
  at android.app.Activity.onKeyUp(Activity.java:2808)
  at android.view.KeyEvent.dispatch(KeyEvent.java:2702)
  at android.app.Activity.dispatchKeyEvent(Activity.java:3113)
  ...

线程状态:

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 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值