首页 > 其他分享 >ANR问题分析总结

ANR问题分析总结

时间:2024-03-27 11:00:13浏览次数:27  
标签:总结 分析 java 10 线程 ANR android com

前言

ANR(Application Not Responding)应用程序无响应。如果你应用程序在 UI 线程被阻塞太长时间,就会出现 ANR,通常出现 ANR,系统会弹出一个提示提示框,让用户知道,该程序正在被阻塞,是否继续等待还是关闭。

ANR类型

出现ANR的一般有以下几种类型:

类型说明logcat日志关键字
KeyDispatchTimeout(常见)input事件在5S内没有处理完成发生了ANRInput event dispatching timed out
BroadcastTimeout前台Broadcast:onReceiver在10S内没有处理完成发生ANR
后台Broadcast:onReceiver在60s内没有处理完成发生ANR
Timeout of broadcast BroadcastRecord
ServiceTimeout前台Service:onCreate,onStart,onBind等生命周期在20s内没有处理完成发生ANR
后台Service:onCreate,onStart,onBind等生命周期在200s内没有处理完成发生ANR
Timeout executing service
ContentProviderTimeoutContentProvider 在10S内没有处理完成发生ANRtimeout publishing content providers
一、导出并查看 ANR 日志

执行命令:

adb bugreport bugreport.zip
adb pull /data/debuglogger/mobilelog

可以导出设备所有 bug 日志,执行命令后,在指定文件夹内得到一个 zip 文件,将文件解压后打开,文件目录如下所示:

其中,设备的 anr 日志会保存在该路径下:C:\Users\xxx\Desktop\bugreport\FS\data\anr,如图:

另外,该文件 C:\Users\xxx\Desktop\bugreport\bugreport-100110603-TP1A.220624.014-2022-10-12-09-49-59.txt 内也有有 anr 日志的打印,我们可以通过以下关键词搜索该文件的一些异常信息,如:

  • “main” prio= 搜索 anr 相关信息
  • beginning of crash 搜索 crash 相关信息
  • CPU usage from 搜索 cpu 使用信息
二、ANR 日志如何分析

一个 ANR 日志,会包含当前设备中所有进程的使用情况,每个进程开头都会
----- pid 17376 at date ----- 来开头,
----- end 17376 ----- 来结尾,
如下所示:

----- pid 17376 at 2022-10-11 09:52:04.264664750+0800 -----
Cmd line: com.android.vending
...
...
...
----- end 17376 -----

另外,每个进程日志中都会有一些进程内存相关的信息,如:

----- pid 17376 at 2022-06-16 16:56:04 -----
Cmd line: com.android.vending
...
...
Total number of allocations 274640   // 进程创建到现在一共创建了多少对象
Total bytes allocated 13MB   // 进程创建到现在一共申请了多少内存
Total bytes freed 5821KB   // 进程创建到现在一共释放了多少内存
Free memory 4562KB   // 空闲内存(可用内存)
Free memory until GC 4562KB   // GC前的空闲内存
Free memory until OOME 248MB   // OOM之前的可用内存,当这个值很小的时候,已经处于内存紧张状态,应用可能占用了过多的内存
Total memory11MB  // 当前总内存(已用+可用)
Max memory 256MB  // 进程最多能申请的内存 
...
----- end 17376 -----

另外,每个进程日志中都会有进程堆栈信息,堆栈信息非常重要,它展示了发生 ANR 的进程当前的所有线程状态。如下所示:

----- pid 17376 at 2022-06-16 16:56:04 -----
Cmd line: com.android.vending
...
suspend all histogram:  Sum: 141.888ms 99% C.I. 0.012ms-91.709ms Avg: 4.892ms Max: 100.514ms
DALVIK THREADS (56):
"Signal Catcher" daemon prio=10 tid=6 Runnable
  | group="system" sCount=0 ucsCount=0 flags=0 obj=0x132c08e0 self=0xb400007dceb186f0
  | sysTid=17386 nice=-20 cgrp=default sched=0/0 handle=0x7c47bdbcb0
  | state=R schedstat=( 44080464 23366075 22 ) utm=3 stm=0 core=2 HZ=100
  | stack=0x7c47ae4000-0x7c47ae6000 stackSize=991KB
  | held mutexes= "mutator lock"(shared held)
  native: #00 pc 00000000005376cc  /apex/com.android.art/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+128) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #01 pc 00000000006f0e24  /apex/com.android.art/lib64/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool, BacktraceMap*, bool) const+236) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #02 pc 00000000006fe6b0  /apex/com.android.art/lib64/libart.so (art::DumpCheckpoint::Run(art::Thread*)+208) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #03 pc 0000000000364174  /apex/com.android.art/lib64/libart.so (art::ThreadList::RunCheckpoint(art::Closure*, art::Closure*)+440) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #04 pc 00000000006fce50  /apex/com.android.art/lib64/libart.so (art::ThreadList::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, bool)+280) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #05 pc 00000000006fc844  /apex/com.android.art/lib64/libart.so (art::ThreadList::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+292) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #06 pc 00000000006d5914  /apex/com.android.art/lib64/libart.so (art::Runtime::DumpForSigQuit(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)+184) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #07 pc 00000000006e19c0  /apex/com.android.art/lib64/libart.so (art::SignalCatcher::HandleSigQuit()+468) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #08 pc 0000000000573e40  /apex/com.android.art/lib64/libart.so (art::SignalCatcher::Run(void*)+264) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #09 pc 00000000000c1e40  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 037ccd4f6c32456866be69c5a0a56591)
  native: #10 pc 0000000000054b50  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 037ccd4f6c32456866be69c5a0a56591)
  (no managed stack frames)
"main" prio=5 tid=1 Waiting
  | group="main" sCount=1 ucsCount=0 flags=1 obj=0x720c41e8 self=0xb400007dceb13380
  | sysTid=17376 nice=0 cgrp=default sched=0/0 handle=0x7f1ae4f4f8
  | state=S schedstat=( 520024534 625550234 691 ) utm=28 stm=23 core=5 HZ=100
  | stack=0x7fea717000-0x7fea719000 stackSize=8188KB
  | held mutexes=
  at jdk.internal.misc.Unsafe.park(Native method)
  - waiting on an unknown object
  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:194)
  at aidy.get(PG:5)
  at aihp.c(PG:1)
  at gdu.az(PG:2)
  at gge.j(PG:33)
  - locked <0x07048dde> (a com.google.android.finsky.application.classic.ClassicApplication)
  at gge.onCreate(PG:3)
  at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1266)
  at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6826)
  at android.app.ActivityThread.-$$Nest$mhandleBindApplication(unavailable:0)
  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2171)
  at android.os.Handler.dispatchMessage(Handler.java:106)
  at android.os.Looper.loopOnce(Looper.java:201)
  at android.os.Looper.loop(Looper.java:288)
  at android.app.ActivityThread.main(ActivityThread.java:7941)
  at java.lang.reflect.Method.invoke(Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:569)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1015)
 ...
"Jit thread pool worker thread 0" daemon prio=5 tid=8 Native
  | group="system" sCount=1 ucsCount=0 flags=1 obj=0x132c09d0 self=0xb400007dceb43e40
  | sysTid=17389 nice=9 cgrp=default sched=0/0 handle=0x7c478e1cb0
  | state=S schedstat=( 46231998 254143847 68 ) utm=3 stm=0 core=7 HZ=100
  | stack=0x7c477e2000-0x7c477e4000 stackSize=1023KB
  | held mutexes=
  native: #00 pc 000000000004f66c  /apex/com.android.runtime/lib64/bionic/libc.so (syscall+28) (BuildId: 037ccd4f6c32456866be69c5a0a56591)
  native: #01 pc 000000000047cc80  /apex/com.android.art/lib64/libart.so (art::ConditionVariable::WaitHoldingLocks(art::Thread*)+140) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #02 pc 000000000047cb18  /apex/com.android.art/lib64/libart.so (art::ThreadPool::GetTask(art::Thread*)+120) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #03 pc 0000000000619810  /apex/com.android.art/lib64/libart.so (art::ThreadPoolWorker::Run()+136) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #04 pc 00000000006196f0  /apex/com.android.art/lib64/libart.so (art::ThreadPoolWorker::Callback(void*)+160) (BuildId: 56e704c544e6c624201be2ab4933e853)
  native: #05 pc 00000000000c1e40  /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 037ccd4f6c32456866be69c5a0a56591)
  native: #06 pc 0000000000054b50  /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: 037ccd4f6c32456866be69c5a0a56591)
  (no managed stack frames)
...
----- end 17376 -----

如上截图中,有三个线程,一个是 Signal Catcher 线程,一个是 main 线程,一个是 Jit thread pool worker thread 0 ,他们的线程状态分别是 Runnableblockednative 状态。
而在 Java 中,线程状态有6种,如下所示:

  • NEW - 创建状态:当我们new一个Thread的时候,线程就处于创建状态;
  • RUNNABLE - 就绪或运行状态:当我们调用线程的 start() 方法,线程就会进入该状态;

另外,还有两种情况也会使线程进入就绪状态:

  • 线程之前处于阻塞状态,如果阻塞解除了,也会进入就绪状态
  • 线程之前处于运行状态,如果执行了 Thread.yield() 方法,则线程会进入就绪状态
  • BLOCKED - 阻塞状态:该状态下,线程正在阻塞等待某个锁。
  • WATING - 等待状态:当调用了以下某一个方法,线程就会处于等待状态:

Object.wait
Thread.join
LockSupport.park
处于等待状态的线程正在等待另一个线程执行特定操作,例如:

  • 在一个对象上调用了 Object.wait() 的线程正在等待另一个线程调用 Object.notify() 或 Object.notifyAll() 。
  • 已调用 Thread.join() 的线程正在等待指定线程终止。
  • TIMED_WAITING - 定时等待状态:指定等待时间的等待状态,当调用以下具有指定正等待时间的方法之一,线程就会处于定时等待状态:

Thread.sleep(long millis)
Object.wait(long timeout)
Thread.join(long millis)
LockSupport.parkNanos(long nanos)
LockSupport .parkUntil(long deadline)

  • TERMINATED - 终止状态:终止状态,线程已完成执行就会进入此状态。

那么,上述日志中的 native 状态是什么呢?
其实该状态是 cpp 代码中定义的线程状态,他跟 java 定义的线程状态关系如下:

java thread 状态cpp thread状态说明
TERMINATEDZOMBIE线程死亡,终止运行
RUNNABLERUNNING/RUNNABLE线程可运行或正在运行
TIMED_WAITINGTIMED_WAIT执行了带有超时参数的wait, sleep或join函数
BLOCKEDMONITOR线程阻塞,等待获取对象锁
WAITINGWAIT执行了无超时参数的wait函数
NEWINITIALIZING新建,正在初始化,为其分配资源
NEWSTARTING新建,正在启动
RUNNABLENATIVE正在执行JNI本地函数
WAITINGVMWAIT正在等待VM资源
RUNNABLESUSPENDED线程暂停,通常是由于GC或debug被暂停
UNKNOWN未知状态

由上可知,native 状态对应的 java 线程状态是 runnable 状态。
堆栈信息是我们分析 ANR 的第一个重要的信息,一般来说:

  • 主线程处于 BLOCK / WAITING / TIMEWAITING 状态,基本上是函数阻塞导致的 anr
  • 若主线程无异常,则应该排查 CPU 负载和内存环境等其他因素

另外,在 anr 日志中,还有一些常见参数,他们的含义如下:

参数含义
mainmain标识是主线程,如果是线程,那么命名成“Thread-X”的格式,x表示线程id,逐步递增。
prio线程优先级,默认是5
tidtid不是线程的id,是线程唯一标识ID
group是线程组名称
sCount该线程被挂起的次数
dsCount是线程被调试器挂起的次数
obj对象地址
self该线程Native的地址
sysTid是线程号(主线程的线程号和进程号相同)
nice是线程的调度优先级
sched分别标志了线程的调度策略和优先级
cgrp调度归属组
handle线程处理函数的地址
state是调度状态
schedstat从 /proc/[pid]/task/[tid]/schedstat读出,三个值分别表示线程在cpu上执行的时间、线程的等待时间和线程执行的时间片长度,不支持这项信息的三个值都是0;
utm是线程用户态下使用的时间值(单位是jiffies)
stm是内核态下的调度时间值
core是最后执行这个线程的cpu核的序号
三、分析

1.通过在 events_log 中检索 am_anr 关键字,就可以找到发生ANR的进程,譬如以下日志:

10-16 00:48:27 820 907 I am_anr: [0,29533,com.android.systemui,1082670605,Broadcast of Intent { act=android.intent.action.TIME_TICK flg=0x50000114 (has extras) }]

表示在 10-16 00:48:27 这个时刻,PID29533 进程发生了 ANR,进程名是 com.android.systemui
接下来可以在 sys_log 检索 ANR in 关键字,找到发生 ANR 前后的 CPU 使用情况:

10-16 00:50:10 820 907 E ActivityManager: ANR in com.android.systemui, time=130090695
10-16 00:50:10 820 907 E ActivityManager: Reason: Broadcast of Intent { act=android.intent.action.TIME_TICK flg=0x50000114 (has extras) }
10-16 00:50:10 820 907 E ActivityManager: Load: 30.4 / 22.34 / 19.94
10-16 00:50:10 820 907 E ActivityManager: Android time :[2015-10-16 00:50:05.76] [130191,266]
10-16 00:50:10 820 907 E ActivityManager: CPU usage from 6753ms to -4ms ago:
10-16 00:50:10 820 907 E ActivityManager:   47% 320/netd: 3.1% user + 44% kernel / faults: 14886 minor 3 major
10-16 00:50:10 820 907 E ActivityManager:   15% 10007/com.sohu.sohuvideo: 2.8% user + 12% kernel / faults: 1144 minor
10-16 00:50:10 820 907 E ActivityManager:   13% 10654/hif_thread: 0% user + 13% kernel
10-16 00:50:10 820 907 E ActivityManager:   11% 175/mmcqd/0: 0% user + 11% kernel
10-16 00:50:10 820 907 E ActivityManager:   5.1% 12165/app_process: 1.6% user + 3.5% kernel / faults: 9703 minor 540 major
10-16 00:50:10 820 907 E ActivityManager:   3.3% 29533/com.android.systemui: 2.6% user + 0.7% kernel / faults: 8402 minor 343 major
10-16 00:50:10 820 907 E ActivityManager:   3.2% 820/system_server: 0.8% user + 2.3% kernel / faults: 5120 minor 523 major
10-16 00:50:10 820 907 E ActivityManager:   2.5% 11817/com.netease.pomelo.push.l.messageservice_V2: 0.7% user + 1.7% kernel / faults: 7728 minor 687 major
10-16 00:50:10 820 907 E ActivityManager:   1.6% 11887/com.android.email: 0.5% user + 1% kernel / faults: 6259 minor 587 major
10-16 00:50:10 820 907 E ActivityManager:   1.4% 11854/com.android.settings: 0.7% user + 0.7% kernel / faults: 5404 minor 471 major
10-16 00:50:10 820 907 E ActivityManager:   1.4% 11869/android.process.acore: 0.7% user + 0.7% kernel / faults: 6131 minor 561 major
10-16 00:50:10 820 907 E ActivityManager:   1.3% 11860/com.tencent.mobileqq: 0.1% user + 1.1% kernel / faults: 5542 minor 470 major
...
10-16 00:50:10 820 907 E ActivityManager:  +0% 12832/cat: 0% user + 0% kernel
10-16 00:50:10 820 907 E ActivityManager:  +0% 13211/zygote64: 0% user + 0% kernel
10-16 00:50:10 820 907 E ActivityManager: 87% TOTAL: 3% user + 18% kernel + 64% iowait + 0.5% softirq

这一段日志它包含的信息量非常多:

  • 发生 ANR 的时间:events_log 中,ANR 的时间是 00:48:27,因为 AMS.appNotResponding() 首先会打印 events_log,然后再打印 syst_log, 所以,在 syst_log 中,找到ANR的时间是 00:50:10。可以从这个时间点之前的日志中,还原ANR出现时系统的运行状态。
  • 打印ANR日志的进程:ANR日志都是在 system_server 进程的AMS线程打印的,在events_log和sys_log中,都能看到 820 和 907, 所以system_server的PID是 802,AMS 线程的 TID 是 907。ANR的监测机制实现在 AMS线程,分析一些受系统影响的ANR,需要知道system_server进程的运行状态。
  • 发生ANR的进程:ANR in关键字就表明了当前ANR的进程是com.android.system.ui,通过events_log,知道进程的PID是 29533。
  • CPU使用统计时间段:CPU usage from XX to XX ago关键字表明了这是在ANR发生之前一段时间内的CPU统计。 类似的还有CPU usage from XX to XX after关键字,表明是ANR发生之后一段时间内的CPU统计。
  • 发生ANR的原因:Reason关键字表明了当前发生ANR的原因是,处理TIME_TICK广播消息超时。 隐含的意思是TIME_TICK是一个串行广播消息,在 29533 的主线程中,执行BroadcastReceiver.onReceive()方法已经超过10秒。(也有可能时其他原因,导致systemui进程分配不到CPU时间,从而主线程处理广播消息超时,发生了ANR。)

2.Blocked——ANR

Blocked关键字,在 ANR 日志里可以直接搜索 Blocked,看个例子:

"main" prio=5 tid=1 Blocked
  | group="main" sCount=1 dsCount=0 obj=0x75bd5818 self=0x7f8549a000
  | sysTid=29533 nice=0 cgrp=bg_non_interactive sched=0/0 handle=0x7f894bbe58
  | state=S schedstat=( 289080040422 93461978317 904874 ) utm=20599 stm=8309 core=0 HZ=100
  | stack=0x7fdffda000-0x7fdffdc000 stackSize=8MB
  | held mutexes=
  at com.mediatek.anrappmanager.MessageLogger.println(SourceFile:77)
  - waiting to lock <0x26b337a3> (a com.mediatek.anrappmanager.MessageLogger) held by thread 49
  at android.os.Looper.loop(Looper.java:195)
  at android.app.ActivityThread.main(ActivityThread.java:5718)
  at java.lang.reflect.Method.invoke!(Native method)
  at java.lang.reflect.Method.invoke(Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:975)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)

可以发现主线程 Blocked,并且这里有一行:

- waiting to lock <0x26b337a3> (a com.mediatek.anrappmanager.MessageLogger) held by thread 49

其含义就是,主线程正在被 block, 其正在等待 线程49 释放锁,最终因此导致出现了 ANR。
可以接着搜关键字 tid=49,如果简单的话一般会是:

"xxxThread" prio=5 tid=49 Sleeping

基本也可以定位到问题。

3.Slepping——ANR

Slepping关键字,在 ANR 日志里可以直接搜索 Slepping,看个例子:
MainActivity 代码如下:

class MainActivity : AppCompatActivity() {   
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
    /**
     * 点击睡眠 10s
     */
    fun clickToSleep(view: View) {
        Thread.sleep(10_000)
    }
}

当点击按钮睡眠 10s 后,我们左滑或者点击返回键退出 MainActivity(由于主线程正在睡眠,所以此时是无法退出成功的),等待一段时间,系统将会弹出 ANR 弹窗。

"main" prio=5 tid=1 Sleeping
  | group="main" sCount=1 dsCount=0 flags=1 obj=0x72e0ee78 self=0x79aafbcc00
  | sysTid=16356 nice=-10 cgrp=default sched=0/0 handle=0x79ac524ed0
  | state=S schedstat=( 1075827038 33414740 291 ) utm=93 stm=14 core=2 HZ=100
  | stack=0x7fe35ed000-0x7fe35ef000 stackSize=8192KB
  | held mutexes=
  at java.lang.Thread.sleep(Native method)
  - sleeping on <0x04fbafa5> (a java.lang.Object)
  at java.lang.Thread.sleep(Thread.java:440)
  - locked <0x04fbafa5> (a java.lang.Object)
  at java.lang.Thread.sleep(Thread.java:356)
  at com.example.demoproject.view.MainActivity.clickToSleep(MainActivity.kt:57)
  at java.lang.reflect.Method.invoke(Native method)
  at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:441)
  at android.view.View.performClick(View.java:7259)
  at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1194)
  at android.view.View.performClickInternal(View.java:7236)
  at android.view.View.access$3600(View.java:801)
  at android.view.View$PerformClick.run(View.java:27896)
  at android.os.Handler.handleCallback(Handler.java:883)
  at android.os.Handler.dispatchMessage(Handler.java:100)
  at android.os.Looper.loop(Looper.java:214)
  at android.app.ActivityThread.main(ActivityThread.java:7397)
  at java.lang.reflect.Method.invoke(Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)

从堆栈信息中也很容易发现,在执行到 MainActivity.clickToSleep 方法时,线程进行了睡眠,最终导致 ANR。

4.耗时或死循环方法

例子如下:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
   
    fun click(view: View) {
        doSomething()
    }
    private fun doSomething() {
        // 注意这里死循环
        while (true) {
            Log.i("testLog", "doSomething.. 当前线程名称=${Thread.currentThread().name} 线程id=${Thread.currentThread().id}")
        }
    }
}

当我们点击按钮时,会在主线程通过一个死循环不断打印 log,因此 doSomething() 方法我们可以认为是一个耗时方法,点击按钮后,我们左滑或者点击返回键退出 MainActivity(由于主线程正在忙碌中,所以此时是无法退出成功的),等待一段时间,系统将会弹出 ANR 弹窗。
ANR日志如下:

----- pid 13231 at 2022-06-17 14:23:41 -----
Cmd line: com.example.demoproject
...
"main" prio=5 tid=1 Runnable
  | group="main" sCount=0 dsCount=0 flags=0 obj=0x72b20e78 self=0x77fe5a6c00
  | sysTid=13231 nice=-10 cgrp=default sched=0/0 handle=0x77ffb0eed0
  | state=R schedstat=( 31694533124 58819622 723 ) utm=1310 stm=1859 core=5 HZ=100
  | stack=0x7fdc2b7000-0x7fdc2b9000 stackSize=8192KB
  | held mutexes= "mutator lock"(shared held)
  native: #00 pc 00000000004108e8  /apex/com.android.runtime/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+140)
  native: #01 pc 00000000004f8040  /apex/com.android.runtime/lib64/libart.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char>>&, bool, BacktraceMap*, bool) const+512)
  native: #02 pc 000000000051297c  /apex/com.android.runtime/lib64/libart.so (art::DumpCheckpoint::Run(art::Thread*)+828)
  native: #03 pc 00000000004f8d4c  /apex/com.android.runtime/lib64/libart.so (art::Thread::RunCheckpointFunction()+176)
  native: #04 pc 00000000003713fc  /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::CheckJNI::ReleaseStringCharsInternal(char const*, _JNIEnv*, _jstring*, void const*, bool, bool)+1356)
  native: #05 pc 00000000001507cc  /system/lib64/libandroid_runtime.so (android::android_util_Log_println_native(_JNIEnv*, _jobject*, int, int, _jstring*, _jstring*)+232)
  at android.util.Log.println_native(Native method)
  at android.util.Log.i(Log.java:176)
  at com.example.demoproject.view.MainActivity.doSomething(MainActivity.kt:52)
  at com.example.demoproject.view.MainActivity.click2(MainActivity.kt:36)
  at java.lang.reflect.Method.invoke(Native method)
  at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:441)
  at android.view.View.performClick(View.java:7259)
  at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1194)
  at android.view.View.performClickInternal(View.java:7236)
  at android.view.View.access$3600(View.java:801)
  at android.view.View$PerformClick.run(View.java:27896)
  at android.os.Handler.handleCallback(Handler.java:883)
  at android.os.Handler.dispatchMessage(Handler.java:100)
  at android.os.Looper.loop(Looper.java:214)
  at android.app.ActivityThread.main(ActivityThread.java:7397)
  at java.lang.reflect.Method.invoke(Native method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
...
----- end 16808 -----

发现主线程正处于 Runnable 状态,并不是处于空闲状态,堆栈信息中有一行关键日志:

at com.example.demoproject.view.MainActivity.doSomething(MainActivity.kt:52)

各关键字:am_anr、ANR in、Reason、Blocked、Slepping。

标签:总结,分析,java,10,线程,ANR,android,com
From: https://blog.csdn.net/u010345983/article/details/136376704

相关文章

  • default_statistics_target参数对PG和MogDB性能影响测试和分析
    default_statistics_target参数对PG和MogDB性能影响测试和分析本文出处:https://www.modb.pro/db/230160前段时间在某客户生产环境优化PG查询性能时发现一个很有意思的现象,一个统计信息相关参数可以很大程度上影响SQL的性能。近期在学习MogDB,就对比PG和MogDB做了个......
  • 网络攻防中黑客常用的十大渗透测试演练系统,百款渗透测试工具集合,安卓防逆向、防动态分
    网络攻防中黑客常用的十大渗透测试演练系统,百款渗透测试工具集合,安卓防逆向、防动态分析、渗透测试及加固详细教程。对目标机器进行全面的渗透测试是一个复杂的过程,需要遵循一系列的步骤来确保系统的安全性。以下是一个详细的渗透测试流程,包括关键步骤和一些基本的命令或......
  • 网络攻防中黑客攻击之后的渗透入侵溯源,详细案例一步步实践分析,详细介绍技术手段和使用
    网络攻防中黑客攻击之后的渗透入侵溯源,详细案例一步步实践分析,详细介绍技术手段和使用工具。黑客攻击后的渗透入侵溯源是一个复杂的过程,旨在确定攻击的来源、方法、时间和动机,以便采取适当的应对措施并防止未来的攻击。溯源工作通常由网络安全团队或专业的取证分析师执行,......
  • 3.27每日总结
    某公司欲建设一个房屋租赁服务系统,统一管理房主和租赁者的信息,提供快捷的租赁服务。本系统的主要功能描述如下:1.登记房主信息。记录房主的姓名、住址、身份证号和联系电话等信息,并写入房主信息文件。2.登记房屋信息。记录房屋的地址、房屋类型(如平房、带阳台的楼房、独立式住......
  • 软件体系架构课堂测试–架构分析
    某大银行的一位银行卡办公室的收账经理Liz遇到了一个问题。她每周都收到一份过期未付款的账户名单。这份报告已经从两年前的250个账户增加到现在的1250个账户。为了确定那些严重拖欠债务的账户,Liz需要通读这份报告。严重拖欠债务的账户由几个不同的规则确定,每个规则都要求Liz检查......
  • 软件体系架构课堂测试–-架构分析
    某公司欲建设一个房屋租赁服务系统,统一管理房主和租赁者的信息,提供快捷的租赁服务。本系统的主要功能描述如下:1.登记房主信息。记录房主的姓名、住址、身份证号和联系电话等信息,并写入房主信息文件。2.登记房屋信息。记录房屋的地址、房屋类型(如平房、带阳台的楼房、独立式住......
  • Xilinx ZYNQ 7000+Vivado2015.2系列(二)之奇数分频和逻辑分析仪(ILA)的使用
    前言:偶数分频容易得到:N倍偶数分频,可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N/2-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循环下去。奇数分频如何得到呢?第一部分 奇数分频奇数分频方法:N倍奇数分频,首先进行上升沿触发进行......
  • 石家庄铁道大学2024年春季 2020 级课堂测试试卷—数据分析练习
    石家庄铁道大学2024年春季  2020级课堂测试试卷—数据分析练习课程名称: 大数据库技术与应用  任课教师:王建民  考试时间: 实现为止 分钟  一、 原始数据: 二、 地域维度标准化:地域属性在科技成果分析中作为一个重要维度,其标准取值非常必要,目前我国采用的标......
  • 软件需求与分析课堂测试十一 —综合案例建模分析
    软件需求与分析课堂测试十一—综合案例建模分析(100分)【整体背景】随着公司业务的发展以及在AI和人工智能领域的持续深入,需要把部分工作外包。外包可以更加有效的利用社会资源,优化资源利用率。但在外包实践中,遇到诸如任务跟踪,人员管理,资源访问控制的问题,希望开发一套外包人员......
  • 软件需求与分析课堂测试十——综合案例分析
    软件需求与分析课堂测试十——综合案例分析(5分) 班级:信2105-2班    学号:20213849   姓名:燕烁天根据下列案例需求描述,回答相关问题:有一个对外营业的会议中心,有各种不同规格的会议室,为用户提供以下服务:1、用户可以按照会议人数、会议时间预订会议室。可以只预订1次,也可......