Comment gérer :java.util.de façon concomitante.TimeoutException: android.os.BinderProxy.finalize() a expiré au bout de 10 secondes d'erreurs?
Nous voyons un certain nombre de TimeoutExceptions
dans GcWatcher.finalize, BinderProxy.finalize
, et PlainSocketImpl.finalize
. Plus de 90% d'entre eux arrivent sur Android 4.3. Nous sommes à recevoir des rapports de ce de Crittercism des utilisateurs dans le domaine.
L'erreur est une variation de: "com.android.internal.BinderInternal$GcWatcher.finalize() timed out after 10 seconds
"
java.util.concurrent.TimeoutException: android.os.BinderProxy.finalize() timed out after 10 seconds
at android.os.BinderProxy.destroy(Native Method)
at android.os.BinderProxy.finalize(Binder.java:459)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:187)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:170)
at java.lang.Thread.run(Thread.java:841)
Jusqu'à présent, nous n'avons pas encore eu la chance de reproduire le problème dans la maison ou à comprendre ce qui a causé il.
Les idées de ce que peut être la cause?
Aucune idée de la façon de débogage et de déterminer quelle partie de l'application en est la cause?
Tout ce qui jette la lumière sur la question aide.
Plus Stacktraces:
1 android.os.BinderProxy.destroy
2 android.os.BinderProxy.finalize Binder.java, line 482
3 java.lang.Daemons$FinalizerDaemon.doFinalize Daemons.java, line 187
4 java.lang.Daemons$FinalizerDaemon.run Daemons.java, line 170
5 java.lang.Thread.run Thread.java, line 841
2
1 java.lang.Object.wait
2 java.lang.Object.wait Object.java, line 401
3 java.lang.ref.ReferenceQueue.remove ReferenceQueue.java, line 102
4 java.lang.ref.ReferenceQueue.remove ReferenceQueue.java, line 73
5 java.lang.Daemons$FinalizerDaemon.run Daemons.java, line 170
6 java.lang.Thread.run
3
1 java.util.HashMap.newKeyIterator HashMap.java, line 907
2 java.util.HashMap$KeySet.iterator HashMap.java, line 913
3 java.util.HashSet.iterator HashSet.java, line 161
4 java.util.concurrent.ThreadPoolExecutor.interruptIdleWorkers ThreadPoolExecutor.java, line 755
5 java.util.concurrent.ThreadPoolExecutor.interruptIdleWorkers ThreadPoolExecutor.java, line 778
6 java.util.concurrent.ThreadPoolExecutor.shutdown ThreadPoolExecutor.java, line 1357
7 java.util.concurrent.ThreadPoolExecutor.finalize ThreadPoolExecutor.java, line 1443
8 java.lang.Daemons$FinalizerDaemon.doFinalize Daemons.java, line 187
9 java.lang.Daemons$FinalizerDaemon.run Daemons.java, line 170
10 java.lang.Thread.run
4
1 com.android.internal.os.BinderInternal$GcWatcher.finalize BinderInternal.java, line 47
2 java.lang.Daemons$FinalizerDaemon.doFinalize Daemons.java, line 187
3 java.lang.Daemons$FinalizerDaemon.run Daemons.java, line 170
4 java.lang.Thread.run
Jamais l'esprit, trouvé bugzilla.mozilla.org/show_bug.cgi?id=864102 je peux aussi confirmer affecte nos applications, on sent comme un Google Play Services de problème
Merci de me le rappeler, j'ai ajouté plein de trace de pile.
La ligne de code qui l'erreur est levée a été introduit à la Version 4.3_r1, qui a été communiqué dans le 5 juin 2013. Peut-être le problème qui se passe depuis.
La version d'Android 4.2.2 également commencé à lever cette exception peut-être de son google play mise à jour de la source.
OriginalL'auteur emmby | 2014-06-03
Vous devez vous connecter pour publier un commentaire.
Divulgation complète - je suis l'auteur de parler dans TLV DroidCon.
J'ai eu la chance d'examiner cette question dans de nombreuses applications Android, et d'en discuter avec d'autres développeurs qui ont rencontré - et nous nous sommes tous au même point: ce problème ne peut pas être évitée, seulement réduit.
J'ai pris un peu plus près l'implémentation par défaut de l'Android Garbage collector code, pour mieux comprendre pourquoi cette exception est Levée et sur ce que pourrait être les causes possibles. J'ai même trouvé une cause possible pendant l'expérimentation.
La racine du problème est au point un dispositif de "Veille" pendant un certain temps, ce qui signifie que l'OS a décidé d'abaisser la consommation de la batterie par l'arrêt de la plupart des Utilisateurs des Terres des processus pendant un certain temps, et en tournant l'Écran éteint, la réduction des cycles de CPU, etc. La manière dont c'est fait - est sur un système Linux niveau où les processus sont en Pause en milieu de course. Cela peut se produire à tout moment pendant le fonctionnement normal de l'exécution de l'Application, mais il s'arrête à un Natif du système d'appel, comme le changement de contexte est réalisé au niveau du noyau. - C'est où le Dalvik GC rejoint l'histoire.
Le Dalvik code GC (tel que mis en œuvre dans le Dalvik projet dans le PSBA site) n'est pas compliquée morceau de code. Le fonctionnement de base de ce travail est couvert dans mes DroidCon diapositives. ce que je n'ai pas de couverture est la base GC boucle - au moment où le collecteur a une liste d'Objets à finaliser (et détruire). la boucle de la logique à la base peut être simplifiée comme ceci:
finalize()
et appel natifdestroy()
si nécessaire,end_timestamp
,end_timestamp - starting_timestamp
) et comparez-les avec une codés en dur valeur de temporisation de 10 secondes,concurrent.TimeoutException
et de tuer le processus.Maintenant, considérons le scénario suivant:
Application longe faire sa chose. ce n'est pas un Utilisateur face à la demande, il s'exécute en arrière-plan. Au cours de cette opération en arrière-plan, les Objets sont créés, utilisés et doivent être recueillies afin de libérer de la mémoire. L'Application ne prend pas la peine avec un Wakelock, ce qui affecte la batterie de façon défavorable, et semble inutile. cela signifie que l'Application appelle le GC de temps à autre. Normalement, le GC fonctionne sans accroc. Parfois (très rarement) le Système va décider de Dormir dans le milieu de la GC exécuter. Cela se produit si vous exécutez votre application assez longtemps, et de surveiller le Dalvik mémoire journaux de près. Maintenant considérer le timestamp de la logique de base GC en boucle, il est possible de l'appareil pour commencer la course, prendre un start_stamp, et aller dormir à l'
destroy()
appel des indigènes sur un objet système. quand il se réveille et reprend la course, ledestroy()
va se terminer, et la prochaine end_stamp sera le temps qu'il a fallu ledestroy()
appel+le temps de dormir. Si le temps de sommeil a été long plus de 10 secondes, le simultanées.délai d'attente exception sera levée.J'ai vu cela dans les graphiques générés à partir de l'analyse de script python pour Android les Applications du Système, non seulement ma propre surveillé apps. recueillir suffisamment de journaux, vous le verrez par la suite.
Ligne du bas:
Le problème ne peut pas être évitée - vous le rencontrerez si votre application s'exécute en arrière-plan. Vous pouvez atténuer en prenant un wakelock, et empêcher l'appareil de dormir, mais c'est une autre histoire, et un nouveau mal de tête, et peut-être un autre discours dans un autre con.
Vous pouvez minimiser le problème en réduisant GC appels de décisions que le scénario le moins probable. des conseils sont dans les diapositives.
Je n'ai pas encore eu la chance d'aller sur le Dalvik 2 (un.k.un ART) code GC - qui dispose d'une nouvelle Générations de Compactage fonctionnalité, ou effectué des expériences sur Android Lollipop.
Ajouté 7/5/2015:
Après avoir examiné les rapports de Plantage de l'agrégation pour ce crash type, il semble que ces accidents à partir de la version 5.0+ de système d'exploitation Android (Lollipop avec l'ART) ne compte que pour 5% de ce crash type. Cela signifie que l'ART GC changements a réduit la fréquence de ces accidents.
Ajouté 6/1/2016:
Ressemble le projet Android a ajouté beaucoup d'informations sur la façon dont le GC fonctionne en Dalvik 2.0 (un.k.un ART). Vous pouvez lire à ce sujet ici - Débogage de l'ART de la Collecte des Ordures
. Il traite également des outils pour obtenir des informations sur le comportement du GC pour votre application. L'envoi d'un SIGQUIT à votre app processus consistera essentiellement à cause d'une ANR, et le vidage de l'état de l'application dans un fichier journal pour l'analyse.
suppression de tout traitement en arrière-plan fait dans votre application va grandement aider à réduire le problème.
Pour ce qu'il vaut, ce qui se passe encore dans la Guimauve (6.0.1). Cela dit, je n'ai jamais reçu cette erreur une fois. Donc, il ne semble pas être un énorme problème. Je vous remercie pour votre explication approfondie.
Après un certain temps, j'ai eu la nette impression que la résolution de ce problème dans le système d'exploitation est très problématique, et nécessite une coopération entre Google et les Constructeurs. Je ne m'attends pas que cela soit corrigé rapidement.
Je suis l'aide de wakelock mais encore rencontré ce problème sur Android 4.4.2. Mon application a des opérations en arrière-plan, mais principalement conçu pour fonctionner tout au long de la journée tandis que le câble de charge monté. Est-il une autre façon d'atténuer ce problème?
OriginalL'auteur oba
Nous le voyons constamment, partout dans notre application, à l'aide de Crashlytics. Le crash se produit généralement en bas dans la plate-forme de code. Un petit échantillonnage:
Les appareils sur lesquels cela se produit sont très majoritairement (mais pas exclusivement) les appareils fabriqués par Samsung. Qui pourrait tout simplement signifier que la plupart de nos utilisateurs à l'aide de périphériques Samsung; alternativement, il peut indiquer un problème avec des appareils Samsung. Je ne suis pas vraiment sûr.
Je suppose que ce n'est pas vraiment répondre à vos questions, mais je voulais juste insister sur le fait que cela semble tout à fait commun, et n'est pas spécifique à votre application.
J'ai ce problème sur android 4.4.4 avec appareil fabriqué par XIAOMI
Voulais juste mentionner que nous assistons à la majorité de ces accidents sur les tablettes samsung. Pas sûr de ce que samsung a fait différemment avec la façon dont les comprimés de poignée de backgrounded apps.
j'ai ce problème sur android 4.4.4. appareil fabriqué par HUAWEI.
Mon application se bloque après si j'utilise la fuite canaries bibliothèque sur android 5.0.2 appareil de Samsung. Si je désactive la bibliothèque de l'initialisation, l'application fonctionne très bien.
OriginalL'auteur kcoppock
J'ai trouvé quelques diapositives sur ce problème.
http://de.slideshare.net/DroidConTLV/android-crash-analysis-and-the-dalvik-garbage-collector-tools-and-tips
Dans ce diapositives de l'auteur raconte qu'il semble y avoir un problème avec le GC, si il y a beaucoup d'objets ou des objets dans le tas. La diapositive également inclure une référence à un exemple d'application et un script python pour analyser cette question.
https://github.com/oba2cat3/GCTest
https://github.com/oba2cat3/logcat2memorygraph
En outre, j'ai trouvé une astuce en commentaire #3 de ce côté: https://code.google.com/p/android/issues/detail?id=53418#c3
OriginalL'auteur Christopher
Récepteurs de radiodiffusion expire au bout de 10 secondes. Peut-être que le faire un appel asynchrone (mauvais) à partir d'un récepteur de radiodiffusion et de 4,3 fait le détecte.
Pardon si je me trompe, mais je ne pense pas que le récepteur de radiodiffusion timeout les causes de ce crash. C'est une bonne pratique pour éviter les 10s limite, mais c'est une autre question que le demandeur est d'avoir.
J'ai juste 10 secondes sur le cerveau. developer.android.com/training/articles/perf-anr.html IDK si elle était à l'origine du crash.
Votre point est solide et de bonnes pratiques. Toutefois, l'affiche originale a une question précise sur un ensemble spécifique de périphériques. Je conseille d'autres téléspectateurs de ce post pour vérifier la réponse de Christopher et de l'oba réponse si l'on voit les mêmes symptômes (appareils Samsung (esp. Galaxy S 4), etc.)
Je ne suis pas ici pour bash fabricants d'appareils, il serait à l'encontre des termes.
OriginalL'auteur danny117
Nous avons résolu le problème en arrêtant le
FinalizerWatchdogDaemon
.Vous pouvez appeler la méthode dans l'Application du cycle de vie, comme
attachBaseContext()
.Pour la même raison, vous pouvez également spécifique du téléphone fabrication pour résoudre le problème, il est à vous.
Il a travaillé. Mais je ne sais pas Pourquoi cela se produit?.
OriginalL'auteur Enaoi
Une chose qui est toujours vrai, c'est qu'à ce moment, l'appareil serait étouffante de la mémoire (qui est généralement la raison pour GC pour la plupart susceptibles de se déclencher).
Comme mentionné par presque tous les auteurs précédemment, ce problème surfaces quand Android tente d'exécuter GC, tandis que l'application est en arrière-plan. Dans la plupart des cas où nous avons observé, en pause l'application par le verrouillage de l'écran.
Cela peut également indiquer fuite de mémoire quelque part dans l'application ou l'appareil trop chargé, déjà.
Donc, la seule façon légitime de le minimiser est:
OriginalL'auteur Sankalp Sharma
Oui,je suis juste de faire exemple~
Cela ne devrait pas travailler en raison de la constante d'inlining. La modification de la valeur du champ n'affectera pas la valeur inline pour les appelants.
OriginalL'auteur kot32
La finalizeQueue peut-être trop long
je pense que java peut exiger GC.SuppressFinalize() & GC.ReRegisterForFinalize() pour permettre à l'utilisateur de réduire le finalizedQueue longueur explicitement
si la JVM le code source est disponible, peut mettre en œuvre ces méthodes nous-mêmes, tels que la ROM android maker
OriginalL'auteur Yessy
Pour les classes que vous créez (ie. ne font pas partie de l'Android) son possible pour éviter le crash complètement.
Toute classe qui implémente
finalize()
a quelques inévitables probabilité de s'écraser comme expliqué par @oba. Donc, au lieu d'utiliser les finaliseurs pour effectuer le nettoyage, utilisez unPhantomReferenceQueue
.Pour un exemple de vérifier la mise en œuvre de Réagir Natif: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/jni/DestructorThread.java
OriginalL'auteur Ben