Нужно немного разобраться в этой повторяющейся проблеме, ANR keyDispatchingTimedOut - PullRequest
1 голос
/ 13 марта 2011

У меня есть приложение, которое продолжает получать ANR в одном конкретном компоненте, и я не могу понять, что затрачивает время процессора. В последнее время я получаю два вида ANR: натив и ожидание.

 DALVIK THREADS:
"main" prio=5 tid=1 NATIVE
  | group="main" sCount=1 dsCount=0 s=N obj=0x4001d8c0 self=0xccc8
  | sysTid=10569 nice=0 sched=0/0 cgrp=default handle=-1345017816
  | schedstat=( 9041503981 6690216078 17225 )
  at android.view.Surface.lockCanvasNative(Native Method)
  at android.view.Surface.lockCanvas(Surface.java:314)
  at android.view.SurfaceView$3.internalLockCanvas(SurfaceView.java:773)
  at android.view.SurfaceView$3.lockCanvas(SurfaceView.java:756)
  at com.dane.hud.Surfaceview$DrawThread.run(Surfaceview.java:776)
  at com.dane.hud.Surfaceview.onTouchEvent(Surfaceview.java:322)
  at android.view.View.dispatchTouchEvent(View.java:3766)
  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671)
  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
  at android.app.Activity.dispatchTouchEvent(Activity.java:2086)
  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1655)
  at android.view.ViewRoot.handleMessage(ViewRoot.java:1785)
  at android.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loop(Looper.java:123)
  at android.app.ActivityThread.main(ActivityThread.java:4627)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:521)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
  at dalvik.system.NativeStart.main(Native Method)

"Binder Thread #3" prio=5 tid=9 NATIVE
  | group="main" sCount=1 dsCount=0 s=N obj=0x44821de0 self=0x2b9b78
  | sysTid=10585 nice=0 sched=0/0 cgrp=default handle=2857768
  | schedstat=( 726806597 708740243 2395 )
  at dalvik.system.NativeStart.run(Native Method)

"Binder Thread #2" prio=5 tid=6 NATIVE
  | group="main" sCount=1 dsCount=0 s=N obj=0x4476c5e8 self=0x13cbf8
  | sysTid=10574 nice=0 sched=0/0 cgrp=default handle=1213280
  | schedstat=( 767669649 687500005 2512 )
  at dalvik.system.NativeStart.run(Native Method)

"Binder Thread #1" prio=5 tid=5 NATIVE
  | group="main" sCount=1 dsCount=0 s=N obj=0x4476b310 self=0x126f90
  | sysTid=10573 nice=0 sched=0/0 cgrp=default handle=1208144
  | schedstat=( 749938913 622802748 2497 )
  at dalvik.system.NativeStart.run(Native Method)

"Compiler" daemon prio=5 tid=4 VMWAIT
  | group="system" sCount=1 dsCount=0 s=N obj=0x447652a0 self=0x125b80
  | sysTid=10572 nice=0 sched=0/0 cgrp=default handle=1251720
  | schedstat=( 999145549 669586193 5169 )
  at dalvik.system.NativeStart.run(Native Method)

"Signal Catcher" daemon prio=5 tid=3 RUNNABLE
  | group="system" sCount=0 dsCount=0 s=N obj=0x447651e8 self=0x121988
  | sysTid=10571 nice=0 sched=0/0 cgrp=default handle=1251656
  | schedstat=( 16204836 16693113 8 )
  at dalvik.system.NativeStart.run(Native Method)

"HeapWorker" daemon prio=5 tid=2 VMWAIT
  | group="system" sCount=1 dsCount=0 s=N obj=0x431a9650 self=0x1317c0
  | sysTid=10570 nice=0 sched=0/0 cgrp=default handle=1172520
  | schedstat=( 28203003083 34572570617 10984 )
  at dalvik.system.NativeStart.run(Native Method)

и

DALVIK THREADS:
"main" prio=5 tid=1 WAIT
  | group="main" sCount=1 dsCount=0 s=N obj=0x4001d8c0 self=0xccc8
  | sysTid=2428 nice=0 sched=0/0 cgrp=default handle=-1345017816
  | schedstat=( 5054412632 4232574644 11781 )
  at java.lang.Object.wait(Native Method)
  - waiting on <0x4001d950> (a java.lang.VMThread)
  at java.lang.Thread.parkFor(Thread.java:1535)
  at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
  at sun.misc.Unsafe.park(Unsafe.java:317)
  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:131)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:790)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:823)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1153)
  at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:185)
  at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:261)
  at android.view.SurfaceView$3.internalLockCanvas(SurfaceView.java:764)
  at android.view.SurfaceView$3.lockCanvas(SurfaceView.java:756)
  at com.dane.hud.Surfaceview$DrawThread.run(Surfaceview.java:776)
  at com.dane.hud.Surfaceview.onTouchEvent(Surfaceview.java:319)
  at android.view.View.dispatchTouchEvent(View.java:3766)
  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:936)
  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1671)
  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
  at android.app.Activity.dispatchTouchEvent(Activity.java:2086)
  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1655)
  at android.view.ViewRoot.handleMessage(ViewRoot.java:1785)
  at android.os.Handler.dispatchMessage(Handler.java:99)
  at android.os.Looper.loop(Looper.java:123)
  at android.app.ActivityThread.main(ActivityThread.java:4627)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:521)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
  at dalvik.system.NativeStart.main(Native Method)

"Thread-448" prio=5 tid=16 WAIT
  | group="main" sCount=1 dsCount=0 s=N obj=0x447e4b40 self=0x2e5960
  | sysTid=2892 nice=0 sched=0/0 cgrp=default handle=3037856
  | schedstat=( 495635974 519531260 463 )
  at java.lang.Object.wait(Native Method)
  - waiting on <0x447eeb10> (a java.lang.VMThread)
  at java.lang.Thread.parkFor(Thread.java:1535)
  at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
  at sun.misc.Unsafe.park(Unsafe.java:317)
  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:131)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:790)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:823)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1153)
  at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:185)
  at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:261)
  at android.view.SurfaceView$3.internalLockCanvas(SurfaceView.java:764)
  at android.view.SurfaceView$3.lockCanvas(SurfaceView.java:756)
  at com.dane.hud.Surfaceview$DrawThread.run(Surfaceview.java:776)
  at com.dane.hud.HUD.updateWithNewLocation(HUD.java:639)
  at com.dane.hud.HUD.access$3(HUD.java:618)
  at com.dane.hud.HUD$updateEverythingFromGPS.run(HUD.java:573)

"Thread-447" prio=5 tid=15 WAIT
  | group="main" sCount=1 dsCount=0 s=N obj=0x447fb5f0 self=0x2bd690
  | sysTid=2890 nice=0 sched=0/0 cgrp=default handle=2873296
  | schedstat=( 636688219 727813733 545 )
  at java.lang.Object.wait(Native Method)
  - waiting on <0x447fb780> (a java.lang.VMThread)
  at java.lang.Thread.parkFor(Thread.java:1535)
  at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
  at sun.misc.Unsafe.park(Unsafe.java:317)
  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:131)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:790)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:823)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1153)
  at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:185)
  at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:261)
  at android.view.SurfaceView$3.internalLockCanvas(SurfaceView.java:764)
  at android.view.SurfaceView$3.lockCanvas(SurfaceView.java:756)
  at com.dane.hud.Surfaceview$DrawThread.run(Surfaceview.java:776)
  at com.dane.hud.HUD.updateWithNewLocation(HUD.java:639)
  at com.dane.hud.HUD.access$3(HUD.java:618)
  at com.dane.hud.HUD$updateEverythingFromGPS.run(HUD.java:573)

"Thread-446" prio=5 tid=14 WAIT
  | group="main" sCount=1 dsCount=0 s=N obj=0x44823a68 self=0x2ccac0
  | sysTid=2889 nice=0 sched=0/0 cgrp=default handle=2874496
  | schedstat=( 774780280 777496325 693 )
  at java.lang.Object.wait(Native Method)
  - waiting on <0x44786fe8> (a java.lang.VMThread)
  at java.lang.Thread.parkFor(Thread.java:1535)
  at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
  at sun.misc.Unsafe.park(Unsafe.java:317)
  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:131)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:790)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:823)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1153)
  at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:185)
  at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:261)
  at android.view.SurfaceView$3.internalLockCanvas(SurfaceView.java:764)
  at android.view.SurfaceView$3.lockCanvas(SurfaceView.java:756)
  at com.dane.hud.Surfaceview$DrawThread.run(Surfaceview.java:776)
  at com.dane.hud.HUD.updateWithNewLocation(HUD.java:639)
  at com.dane.hud.HUD.access$3(HUD.java:618)
  at com.dane.hud.HUD$updateEverythingFromGPS.run(HUD.java:573)

"Thread-445" prio=5 tid=13 WAIT
  | group="main" sCount=1 dsCount=0 s=N obj=0x447f2288 self=0x2e2a80
  | sysTid=2888 nice=0 sched=0/0 cgrp=default handle=3026032
  | schedstat=( 831634516 815490735 696 )
  at java.lang.Object.wait(Native Method)
  - waiting on <0x447f2418> (a java.lang.VMThread)
  at java.lang.Thread.parkFor(Thread.java:1535)
  at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
  at sun.misc.Unsafe.park(Unsafe.java:317)
  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:131)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:790)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:823)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1153)
  at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:185)
  at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:261)
  at android.view.SurfaceView$3.internalLockCanvas(SurfaceView.java:764)
  at android.view.SurfaceView$3.lockCanvas(SurfaceView.java:756)
  at com.dane.hud.Surfaceview$DrawThread.run(Surfaceview.java:776)
  at com.dane.hud.HUD.updateWithNewLocation(HUD.java:639)
  at com.dane.hud.HUD.access$3(HUD.java:618)
  at com.dane.hud.HUD$updateEverythingFromGPS.run(HUD.java:573)

"Thread-444" prio=5 tid=12 WAIT
  | group="main" sCount=1 dsCount=0 s=N obj=0x447c97c0 self=0x2c4910
  | sysTid=2887 nice=0 sched=0/0 cgrp=default handle=2780792
  | schedstat=( 1249114988 1195007328 1038 )
  at java.lang.Object.wait(Native Method)
  - waiting on <0x447cd918> (a java.lang.VMThread)
  at java.lang.Thread.parkFor(Thread.java:1535)
  at java.lang.LangAccessImpl.parkFor(LangAccessImpl.java:48)
  at sun.misc.Unsafe.park(Unsafe.java:317)
  at java.util.concurrent.locks.LockSupport.park(LockSupport.java:131)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:790)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:823)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1153)
  at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:185)
  at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:261)
  at android.view.SurfaceView$3.internalLockCanvas(SurfaceView.java:764)
  at android.view.SurfaceView$3.lockCanvas(SurfaceView.java:756)
  at com.dane.hud.Surfaceview$DrawThread.run(Surfaceview.java:776)
  at com.dane.hud.HUD.updateWithNewLocation(HUD.java:639)
  at com.dane.hud.HUD.access$3(HUD.java:618)
  at com.dane.hud.HUD$updateEverythingFromGPS.run(HUD.java:573)

"Thread-443" prio=5 tid=11 VMWAIT JIT
  | group="main" sCount=1 dsCount=0 s=Y obj=0x4480cd28 self=0x2d27b0
  | sysTid=2886 nice=0 sched=0/0 cgrp=default handle=2959600
  | schedstat=( 1636657703 1482391360 1374 )
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.addWaiter(AbstractQueuedSynchronizer.java:~562)
  at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1153)
  at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:185)
  at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:261)
  at android.view.Surfa...

Есть идеи? Я перенес операции в новые потоки и, возможно, я не вызываю join (); на них.

Спасибо за любую помощь.

Ответы [ 2 ]

5 голосов
/ 14 марта 2011

Здесь:

http://developer.android.com/guide/practices/design/responsiveness.html

ANR - это когда основной поток блокирует что-либо, поэтому рекомендуется всегда выполнять эту операцию в дочернем потоке:

ЦИТАТА:

Поэтому любой метод, который работает в основной поток должен делать как можно меньше работы насколько это возможно. В частности, Деятельность следует сделать как можно меньше, чтобы установить в ключевых методах жизненного цикла, таких как onCreate () и onResume (). Потенциально долгосрочные операции, такие как операции с сетью или базой данных, или вычислительно дорогие вычисления такие как изменение размера растровых изображений должны быть сделано в дочерней ветке (или в случае операций с базами данных, через асинхронный запрос). Тем не менее, это не значит что твой основной поток следует заблокировать во время ожидания дочерняя нить для завершения - не должна Вы вызываете Thread.wait () или Thread.sleep (). Вместо блокировки в ожидании дочерней нити завершить, ваш основной поток должен предоставить обработчик для дочерних потоков отправить обратно по завершении. Разработка вашего приложения таким образом позволит вашей основной теме остаться реагировать на ввод и, таким образом, избегать ANR диалоги, вызванные 5-секундным вводом Тайм-аут события. Эти же практики следует соблюдать для любого другого потоки, которые отображают пользовательский интерфейс, как они есть также подвержены тем же тайм-аутам.

Я понимаю, что это нелегко, но рекомендация сверху состоит в том, что пользовательский интерфейс должен выполняться не в основном потоке.

С другой стороны, ваш основной поток находится в состоянии «WAIT», что означает использование не асинхронной операции. Возможно, вы хотите попробовать асинхронную опцию, которая должна привести к состоянию TIMED_WAIT, как показано ниже:

Android - как исследовать ANR?

(основной поток в порядке).

Но, как обсуждалось здесь:

http://groups.google.com/group/android-ndk/browse_thread/thread/84d6a9be21f4e579/b83537161b96da82?q=%22Bitmap+creation+and+composition+in+native+code%22#b83537161b96da82

Ваша проблема, которую я подозреваю, состоит в том, что рисование растрового изображения занимает слишком много времени между lockCanvas () и unlockCanvas () - возможно, вы захотите разбить обновление растрового изображения на более мелкие части? И в том же обсуждении также упоминается использование JNI / NDK для вычисления растровых изображений - что не следует делать внутри метода обновления растровых изображений на основе Java - если для выполнения вычислений требуется слишком много времени.

Рекомендуем прочитать:

http://obviam.net/index.php/the-android-game-loop/

Спасибо.

0 голосов
/ 22 августа 2013

Исходя из журналов, единственная причина, по которой я мог подумать, что это могло вызвать ANR:

Насколько я знаю, обычно в Java каждый поток связан с 2 компонентами. Один - счетчик программ, а другой - сборщик мусора. Таким образом, каждый поток будет иметь gc монитор повсюду.

на java.lang.Object.wait (собственный метод) - ожидание <0x4001d950> (java.lang.VMThread)

VMThreads идеально подходят для управления этим аспектом мониторинга gc почти параллельно. Итак, что я мог бы подумать, для вашего сценария, это то, что SurfaceView пытается получить блокировку, но не может, потому что VMThread удерживает блокировку, еще не выпущенную (может быть из-за некоторых основных операций GC), таким образом ожидая, пока vmthread снимет блокировку .

Возможно, вы захотите проверить дамп основного журнала, в котором записаны действия gc, что может дать вам более четкое представление о том, почему gc так сильно загружает процессоры, а затем профилирование приложения может помочь. Jus check.

...