Comment prendre de manière fiable des vidages de tas Java?

9

Mon équipe rencontre des difficultés lorsqu'elle essaie de prendre de bonnes sauvegardes de tas déclenchées par OutOfMemoryErrors. Pour des raisons spécifiques, nous prenons actuellement les vidages avec jmap appelé à partir d'un script bash au lieu d'utiliser l'indicateur HeapDumpOnOutOfMemoryError. Nous utilisons une machine virtuelle Java 1.6 64 bits avec une taille de tas d'environ 3 Go. Nos vidages de tas échouent 90% du temps (estimation approximative).

Y a-t-il quelque chose que nous pouvons faire pour améliorer nos chances d'obtenir un vidage de tas propre que nous pouvons utiliser pour résoudre les problèmes de mémoire? J'ai lu que jmap avait des problèmes majeurs dans Java 1.4 mais que ces problèmes devraient être principalement résolus maintenant.

karlcyr
la source
4
Je nomme cette question pour "le son le plus dégoûtant involontairement".
phoebus
1
Hah- J'ai pensé à le rendre intentionnellement dégoûtant mais je suis nouveau ici et je ne savais pas comment la communauté prendrait ça :).
karlcyr

Réponses:

7

Quel est votre système d'exploitation? (Je ne peux pas ajouter de commentaires).

Pour Solaris, nous obtenons de meilleurs résultats en forçant d'abord un core dump ( gcore <pid>) puis en attachant jmap au fichier core dump ( jmap -heap:format=b <path to java bin> <path to core>)

gcoreest un utilitaire * nix pour générer une image d'un programme en cours d'exécution. Voir lien .

fglez
la source
essayé avec gdb sur linux et cela fonctionne très bien.
Christian
quel JDK a "gcore"? le mien, Sun 32 bits jdk pour linux 1.6.0.20 ne l'a pas.
djangofan
Modifié avec une clarification gcore.
fglez
2

nous avons un JSP qui interroge ManagementFactory.getThreadMXBean () et produit un rapport. Peut ne pas être utile lorsque l'application est en panne, mais si vous interrogez toutes les minutes, vous aurez une idée de ce qui se passe.

Plus d'infos ici.

rytis
la source
2

vous pouvez surveiller votre application via jmx de l'extérieur. lorsque vous connaissez certaines mesures qui indiquent une sortie OutOfMemory, vous pouvez déclencher une exécution jmap avant que l'exception ne soit levée.

Christian
la source
Merci Christian - jmap est-il plus susceptible d'être fiable avant que l'erreur ne soit lancée?
karlcyr
jmap aura encore besoin de temps pour vous obtenir un vidage de tas. mais vous obtiendrez un vidage complet tant que votre jvm / tomcat est principalement responsable.
Christian
Je pense que l'outil le plus propre et le plus facile à faire est "Visual VM". Cela peut être hors de portée, mais créer un plugin personnalisé pour VisualVM qui détecte la condition et prend le vidage automatique depuis VisualVm serait génial à mon humble avis.
djangofan
2

Merci à tous pour vos suggestions.

Ce que nous avons fini par faire, c'est écrire un script pour surveiller activement les journaux de collecte des ordures. D'après notre expérience, les GC complets consécutifs précèdent presque toujours un MOO, de sorte que notre script détecte cet événement, supprime gracieusement le serveur du pool d'équilibrage de charge et force le vidage de tas. Cela a considérablement augmenté notre efficacité.

karlcyr
la source
2

C'est une question assez ancienne, mais je répondrai avec l'espoir que quelqu'un puisse trouver cela utile.

jmap a une option -F (forcer). Cela s'est avéré ne pas fonctionner aussi bien dans le passé pour moi. Si vous devez utiliser l'option -F, je vous recommande de spécifier également le répertoire java.io.tmp dans le cadre de la commande jmap. Il y avait un problème avec JVM version 1.6.22 où l'utilitaire jmap ne fonctionnait pas correctement en raison d'un paramètre de répertoire temporaire.

Vous pouvez également essayer de prendre un vidage de mémoire via gdb. Une fois que vous avez le noyau, jmap peut convertir le noyau en un vidage de tas.

Nick Hristov
la source