Dépannage java fuite de mémoire: la finalisation?
J'ai un comportement anormal de l'application qui semble fuite. Après une brève profiler enquête, plus de mémoire (80%) est détenue par java.lang.ref.Finalizer
instances. Je soupçonne que les finaliseurs de ne pas s'exécuter.
Une cause fréquente de ce qui semble être des exceptions générées à partir de l'outil de finalisation. Cependant, la javadoc de la finalize
méthode de la Object
classe (voir ici par exemple) semble contredire lui-même: il affirme
Si un uncaught exception est levée par la méthode finalize, l'exception est ignoré et la finalisation de cet objet se termine.
mais plus tard, il stipule également que
Toute exception levée par la méthode finalize causes de la finalisation de cet objet d'être arrêtée, mais sinon ignorée.
Que dois-je croire (c'est à dire, est la finalisation interrompue ou pas?), et avez-vous des conseils sur la façon d'enquêter sur de tels apparente des fuites?
Grâce
- Je ne dirais pas que les deux JavaDoc entrées contredire. La seconde citation états: de l'instance en cours de finalisation est terminée mais l'exception est ignorée d'autres objets peuvent encore être finalisé.
- Voyez-vous quels types sont détenues par ces instances? Est-il seulement un ensemble limité de classes ou est-il au-dessus de votre projet?
- La Vie Secrète De La Finaliseur fasterj.com/articles/finalizer1.shtml,
Vous devez vous connecter pour publier un commentaire.
Ma première étape serait de déterminer si c'est une véritable fuite de mémoire ou pas.
Les points soulevés dans les réponses précédentes se rapportent tous à la vitesse à laquelle les objets sont collectés, pas la question de savoir si vos objets sont collectés à tous. Seulement le dernier est une véritable fuite de mémoire.
Nous avons eu une situation identique sur mon projet, et a couru la demande en "slow motion" mode de savoir si nous avons eu une véritable fuite. Nous avons été en mesure de le faire en ralentissant le flux de données d'entrée.
Si le problème disparaît lorsque vous exécutez en "slow motion" mode, alors le problème est probablement l'une de celles suggérées dans les réponses précédentes, c'est à dire le Finaliseur thread ne peut pas traiter le finaliseur file d'attente assez rapide.
Si c'est bien le problème, il semble que vous pourriez avoir besoin de faire quelques non-trivial de refactoring comme décrit dans la page Bringer128 lié, par exemple, à
Les deux citations dire:
Les deux citations aussi dire:
De sorte que les réponses de la première partie de votre question. Je ne sais pas assez sur les Finaliseurs pour vous donner des conseils sur la traque de votre fuite de mémoire si.
EDIT: j'ai trouvé cette page qui pourraient être utiles. Il a des conseils tels que la définition des champs à null manuellement dans les finaliseurs pour permettre à la GC pour les récupérer.
EDIT2: Certaines plus intéressantes, des liens et des citations:
De Anatomie d'une application Java Finaliseur
et aussi
EDIT3: À la lecture de plus de l'Anatomie lien, il semble que de lever des exceptions dans le Finaliseur fil vraiment la ralentit, presque autant que le Thread appelant.rendement(). Vous avez l'air d'être de droite que le Finaliseur fil sera finalement drapeau de l'objet en tant que mesure d'être GC serais même si une exception est levée. Cependant, depuis le ralentissement est important, il est possible que, dans votre cas, le Finaliseur fil n'est pas en gardant en place avec la création de l'objet-et-chutes-de-la portée de taux.
L'article 7 de l'Effectif Java deuxième édition est: "Éviter les finaliseurs". Je vous recommande fortement de le lire. Voici un extrait qui peuvent vous aider à:
"Explicites de résiliation méthodes sont généralement utilisés en combinaison avec des try-finally construire pour assurer la terminaison"
J'ai le même problème avec vous (image ci-dessous). Pour notre cas, cela parce qu'un objet a
wait(0)
dans son finaliser et il n'a jamais notifié, qui bloquent la java.lang.réf.Finaliseur$FinalizerThread. Plus de référencej'ai une fois de voir un problème similaire, qui est le finaliseur thread ne peut pas rattraper le taux de génération des objets finalisables.
ma solution est de faire une boucle fermée de contrôle, par l'utilisation de la MemoryMXBean .getObjectPendingFinalizationCount(), un PD( proportinal et diffrential) contrôle de l'algo pour contrôler la vitesse de générer le finalisable objets, puisque nous avons une entrée unique pour créer, il suffit de sommeil nombre de secondes avec le résultat de la maladie de parkinson algo. il fonctionne bien, même si vous devez régler le paramètre pour le pd algo.
espère que cela aide.