具有阻塞的HeapTaskDaemon线程的ANR [英] ANR with blocked HeapTaskDaemon thread

查看:1364
本文介绍了具有阻塞的HeapTaskDaemon线程的ANR的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Android应用出现ANR错误.跟踪仅显示一个处于阻塞状态的线程(所有其他线程处于等待,睡眠,本地等状态),因此它似乎没有处于死锁状态.我手动(直接)启动了两个线程,因此我大致知道ANR出现在应用程序的哪个部分.不幸的是,我无法理解被阻塞线程的踪迹.也许有人有主意吗?

I get an ANR-error in my Android app. The trace shows only one thread in blocked state (all the others are in state waiting, sleeping, native,..), so it doesn't seem to be in deadlock. There are two threads which I start (directly) manually, so I roughly know in which part of my app the ANR occurs. Unfortunately, I can't make any sense of the trace of the blocked thread. Maybe anyone has an idea?

阻塞线程:

"HeapTaskDaemon" daemon prio=5 tid=6 Blocked
  | group="system" sCount=1 dsCount=0 obj=0x12cfc8e0 self=0xab4b2bf0
  | sysTid=10048 nice=0 cgrp=default sched=0/0 handle=0xf4815930
  | state=S schedstat=( 113876044 26950467 98 ) utm=9 stm=2 core=5 HZ=100
  | stack=0xf4713000-0xf4715000 stackSize=1038KB
  | held mutexes=
  native: pc 0000000000016908  /system/lib/libc.so (syscall+28)
  native: pc 00000000000f604b  /system/lib/libart.so (_ZN3art17ConditionVariable4WaitEPNS_6ThreadE+82)
  native: pc 00000000001cddb1  /system/lib/libart.so (_ZN3art2gc13TaskProcessor7GetTaskEPNS_6ThreadE+92)
  native: pc 00000000001ce2c5  /system/lib/libart.so (_ZN3art2gc13TaskProcessor11RunAllTasksEPNS_6ThreadE+60)
  native: pc 000000000000036f  /data/dalvik-cache/arm/system@framework@boot.oat (Java_dalvik_system_VMRuntime_runHeapTasks__+74)
  at dalvik.system.VMRuntime.runHeapTasks (Native method)
- waiting to lock an unknown object
  at java.lang.Daemons$HeapTaskDaemon.run (Daemons.java:355)
  at java.lang.Thread.run (Thread.java:818) 

这是主线程:

"main" prio=5 tid=1 Waiting
  | group="main" sCount=1 dsCount=0 obj=0x74da03b0 self=0xab36bea8
  | sysTid=10039 nice=13 cgrp=bg_non_interactive sched=0/0 handle=0xf77a2b34
  | state=S schedstat=( 2234944203 2215960664 6968 ) utm=163 stm=60 core=6 HZ=100
  | stack=0xff794000-0xff796000 stackSize=8MB
  | held mutexes=
  at java.lang.Object.wait! (Native method)
- waiting on <0x07456fa0> (a java.lang.Object)
  at java.lang.Thread.parkFor$ (Thread.java:1220)
- locked <0x07456fa0> (a java.lang.Object)
  at sun.misc.Unsafe.park (Unsafe.java:299)
  at java.util.concurrent.locks.LockSupport.park (LockSupport.java:158)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt (AbstractQueuedSynchronizer.java:810)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued (AbstractQueuedSynchronizer.java:843)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire (AbstractQueuedSynchronizer.java:1172)
  at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock (ReentrantLock.java:181)
  at java.util.concurrent.locks.ReentrantLock.lock (ReentrantLock.java:257)
  at android.view.SurfaceView.updateWindow (SurfaceView.java:524)
  at android.view.SurfaceView$3.onPreDraw (SurfaceView.java:179)
  at android.view.ViewTreeObserver.dispatchOnPreDraw (ViewTreeObserver.java:944)
  at android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:2082)
  at android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1134)
  at android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:6050)
  at android.view.Choreographer$CallbackRecord.run (Choreographer.java:860)
  at android.view.Choreographer.doCallbacks (Choreographer.java:672)
  at android.view.Choreographer.doFrame (Choreographer.java:608)
  at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:846)
  at android.os.Handler.handleCallback (Handler.java:739)
  at android.os.Handler.dispatchMessage (Handler.java:95)
  at android.os.Looper.loop (Looper.java:148)
  at android.app.ActivityThread.main (ActivityThread.java:5441)
  at java.lang.reflect.Method.invoke! (Native method)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:738)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:628)

推荐答案

试图提供有关此问题的更多信息.以便为将来的用户提供帮助.

Trying to put more information on this issue. So that it can help future user's.

正如您所说的那样,只有一个线程处于 Blocked 状态,这显然不是死锁.标记为 blocked 的线程通常会告诉您他们试图获取什么 mutex(锁定)以及线程持有的 thread ID(tid)那个锁.

As you said only one thread in Blocked state, it's clear that it is not a Deadlock. Threads marked as blocked will generally tell you what mutex (lock) they are trying to acquire and the thread ID (tid) of the thread holding that lock.

在这种情况下

  • 等待锁定未知对象

上一行既不告诉它试图获取什么互斥锁(锁),也不告诉持有该锁的线程ID.(也许HeapTaskDaemon线程试图锁定某些本机对象,并且由于某些竞争条件而在该try块中).因此,只需检查以下信息并确定您所遇到的问题,并/或提出有根据的猜测以防止出现此问题.

Above line tell neither what mutex(lock) it trying to acquire or thread ID holding that lock. (Maybe HeapTaskDaemon thread trying to lock some native object and in that attempt block due to some race condition). So just check with below information and identify the issue in your case and/or put forward an educated guess to prevent it.

在最新版本的Android上,垃圾回收(GC)通常在名为 HeapTaskDaemon 的后台线程上运行.请注意,大量分配可能意味着更多的CPU资源花费在GC上.

On recent versions of Android, garbage collection(GC) generally runs on a background thread named HeapTaskDaemon. Note that significant amounts of allocation can mean more CPU resources spent on GC.

Systrace将显示GC是否频繁运行,以及 Android Memory Profiler 可以告诉您分配来自何处.如果您在可能的情况下避免分配,尤其是在紧密循环中,那应该没有问题.

Systrace will show you if GC is running frequently, and the Android Memory Profiler can show you where allocations are coming from. If you avoid allocations when you can, especially in tight loops, you shouldn't have a problem.

选中此以获取更多信息.

有关Android中ANR和死锁的更多信息,请选中此链接.

For more information on ANR and Deadlock's in Android check this link.

希望这会有所帮助.

这篇关于具有阻塞的HeapTaskDaemon线程的ANR的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆