Comprendre Java Tas dump


J'essaie de trouver une fuite de mémoire dans mon application depuis une semaine maintenant sans succès. J'ai essayé de faire un vidage de tas et d'utiliser jhat pour regarder le vidage et tracer la fuite de mémoire.

Est-ce une meilleure approche? Quelle est la meilleure façon de traquer la fuite de mémoire avec le vidage de tas.

Remercie de votre aide.

Machine virtuelle utilisée: version java " 1.6.0_25" Environnement d'exécution Java(TM) SE (build 1.6.0_25-b06) Java HotSpot (TM) Machine virtuelle serveur 64 bits (build 20.0-b11, mixte mode)

Les options de JVM: - Xmx1600m-XX:+UseParallelGC-XX:MaxPermSize=256m-Xms1600m-XX:+HeapDumpOnOutOfMemoryError-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-verbose:gc-Xloggc:/tmp/gc.log

OOME Stack trace: N'a pas pu obtenir cela. Le noyau a tué le processus avec une erreur de mémoire insuffisante.

GC Journal : La dernière quelques lignées

48587.245: [GC [PSYoungGen: 407168K->37504K(476160K)] 506729K->137065K(1568448K), 3.0673560 secs] [Times: user=3.53 sys=0.00, real=3.07 secs] 
50318.617: [GC [PSYoungGen: 444224K->37536K(476416K)] 543785K->175177K(1568704K), 3.6635990 secs] [Times: user=3.70 sys=0.00, real=3.67 secs] 
50453.841: [GC [PSYoungGen: 70092K->2912K(476672K)] 207734K->178513K(1568960K), 1.0164250 secs] [Times: user=1.29 sys=0.00, real=1.02 secs] 
50454.858: [Full GC (System) [PSYoungGen: 2912K->0K(476672K)] [PSOldGen: 175601K->137776K(1092288K)] 178513K->137776K(1568960K) [PSPermGen: 60627K->60627K(74368K)], 2.0082140 secs] [Times: user=2.09 sys=0.00, real=2.01 secs] 
52186.496: [GC [PSYoungGen: 407104K->37312K(444416K)] 544880K->175088K(1536704K), 3.3705440 secs] [Times: user=3.93 sys=0.00, real=3.37 secs] 
53919.975: [GC [PSYoungGen: 444416K->37536K(476608K)] 582192K->213032K(1568896K), 3.4242980 secs] [Times: user=4.09 sys=0.00, real=3.42 secs] 
54056.872: [GC [PSYoungGen: 70113K->2880K(476480K)] 245609K->216320K(1568768K), 0.9691980 secs] [Times: user=1.19 sys=0.00, real=0.97 secs] 
54057.842: [Full GC (System) [PSYoungGen: 2880K->0K(476480K)] [PSOldGen: 213440K->99561K(1092288K)] 216320K->99561K(1568768K) [PSPermGen: 60628K->60628K(72320K)], 2.2203320 secs] [Times: user=2.23 sys=0.01, real=2.22 secs] 
55796.688: [GC [PSYoungGen: 406976K->37504K(476160K)] 506537K->137065K(1568448K), 3.2680080 secs]

Mise à jour: Lors de la vérification des messages du journal du noyau, c'est un oom-killer. Mais encore pourquoi le système tuer le processus, n'est-ce pas parce que le processus consomme beaucoup de ressources système ( mémoire ).

Author: Kathir, 2011-07-20

3 answers

La question sur les fuites de mémoire java est un doublon de ceci, que, etc. Pourtant, voici quelques réflexions:

Commencez par prendre quelques instantanés de tas comme décrit dans la réponse liée ci-dessus.

Ensuite, si vous connaissez bien toute l'application, vous pouvez regarder le nombre d'instances et trouver quel type a trop d'instances qui restent. Par exemple, si vous savez qu'une classe est un singleton, mais vous voyez 100 instances de cette classe dans la mémoire, alors c'est sûr signe que quelque chose de drôle se passe là-bas. Alternativement, vous pouvez comparer les instantanés pour trouver quels types d'objets sont de plus en plus nombreux au fil du temps; la clé ici est que vous recherchez une croissance relative sur une certaine période d'utilisation.

Une fois que vous savez ce qui fuit, vous parcourez les références pour trouver la référence racine qui ne peut pas être collectée.

Enfin, rappelez-vous qu'il est possible que vous voyiez une OutOfMemoryError non pas parce que vous fuyez de la mémoire, mais plutôt parce qu'une partie de votre tas est trop petit pour l'application. Pour vérifier si c'est le cas:

  • Incluez dans votre question le type de machine virtuelle que vous utilisez.
  • Incluez dans votre question les arguments que vous transmettez lors du démarrage de java. Quelles sont vos tailles de tas min, max et permgen? Quel type de garbage collector utilisez-vous?
  • Incluez dans votre question la trace de la pile OOME, au cas où il y aurait des informations utiles.
  • Activer verbose GC journalisation, de sorte que vous pouvez voir quelle(s) partie (s) du tas sont en croissance.
  • Activez le paramètre HeapDumpOnOutOfMemoryError , de sorte que vous obteniez un vidage de tas à la toute fin lorsque le processus meurt.

Update : Je ne sais pas ce que signifie "le noyau a tué le processus avec une erreur de mémoire insuffisante" dans votre dernière mise à jour, mais je pense que vous pourriez dire que le linux out of memory killer a été invoqué. Était-ce le cas? Ce problème est complètement séparé de une erreur java OutOfMemoryError. Pour plus de détails sur ce qui se passe, jetez un oeil aux liens de la page que je viens de lier, y compris this et that. Mais la solution à votre problème est simple: utilisez moins de mémoire sur le serveur en question. Je suppose que vous pouvez supprimer la taille de tas min et max du processus java en question, mais vous devez être sûr que vous ne déclencherez pas de véritables OutOfMemoryErrors java. Pouvez-vous déplacer certains processus ailleurs? Pouvez-vous corréler le tueur de mémoire avec le début d'un processus spécifique?

 8
Author: jtoberon, 2017-05-23 11:57:59

Les fuites de mémoire peuvent être résolues en suivant les 3 étapes simples mentionnées ci-dessous:

Étape 1: Capture de vidage de tas au stade précoce

Lancez votre application. Laissez-le prendre du trafic réel pendant 10 minutes. À ce stade, capturez la décharge de tas. Le vidage de tas est essentiellement un instantané de votre mémoire. Il contient tous les objets qui résident dans la mémoire, les valeurs stockées dans ces objets, les références entrantes et sortantes de ces objets. Vous pouvez capturer le vidage de tas peut être capturé en utilisant ce qui suit commande:

   jmap -dump:format=b,file=<file-path> <pid> 

   where

   pid: is the Java Process Id, whose heap dump should be captured
   file-path: is the file path where heap dump will be written in to.

Si vous ne voulez pas utiliser jmap pour capturer des vidages de tas, voici plusieurs autres options pour capturer des vidages de tas.

Étape 2: Capture de vidage de tas avant le crash de l'application

Après avoir fait l'étape #1, laissez l'application s'exécuter. Avant que les plantages d'application prennent un autre vidage de tas une fois de plus. Souvent, il peut être difficile de capturer des décharges de tas avant qu'il ne se bloque, car nous ne savons pas quand l'application va planter. Est-ce après 30 minutes, 3 heures, 3 jours? Ainsi, il est idéal de démarrer votre application avec la propriété JVM suivante:

    -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=<file-path>

    file-path: is the file path where heap dump will be written in to.

Cette propriété déclenchera le vidage de tas lorsque l'application expérimente OutOfMemoryError.

Étape 3: Analyser les décharges de tas

Les objets qui causent des fuites de mémoire augmentent au cours de la période. Si vous pouvez identifier les objets dont la taille a augmenté entre les décharges de tas capturées à l'étape #1 et à l'étape #2, ce sont les objets qui provoquent une fuite de mémoire.

Vous peut envisager d'utiliser l'outil analyseur de vidage de tas tel que HeapHero.io , Eclipse MAT à cet effet. Lorsque vous chargez les décharges de tas dans l'un des outils, une section signale les objets les plus volumineux de la mémoire. Comparez cette section entre le vidage de tas capturé à l'étape #1 et à l'étape #2. Si vous remarquez une croissance anormale d'objets, ce sont eux qui provoquent une fuite de mémoire dans votre application.

 1
Author: Ram Lakshmanan, 2018-03-26 05:31:45

Je vous recommande de revoir mon article original sur ce sujet. L'analyse de vidage de tas Java peut être complexe au début, mais l'utilisation d'outils tels que Eclipse Memory Analyzer simplifie le processus.

Les vidages de tas JVM sont utiles pour les scénarios suivants:

  • Identification d'une fuite de mémoire au niveau Java.
  • Identification d'une fuite de chargeur de classe au niveau Java.
  • Pour en savoir plus sur l'empreinte mémoire de votre application Java sous une certaine charge / trafic scénario.

Référence: Java heap dump: êtes-vous à la hauteur?

 0
Author: P-H, 2013-08-26 15:42:33