149 votes

Comment trouver une fuite de mémoire de Java

Comment trouver une fuite de mémoire en Java (à l'aide par exemple JHat)? J'ai essayé de charger le tas de vidage dans JHat de prendre un look de base. Cependant, je ne comprends pas comment je suis censé être en mesure de trouver la racine de la référence (ref) ou peu importe son nom. Fondamentalement, je peux dire qu'il y a plusieurs centaines de mo de hash table entries ([java.util.HashMap$l'Entrée ou quelque chose comme ça), mais les cartes sont utilisées partout... Est-il un moyen de recherche pour les grandes cartes, ou peut-être la conclusion générale les racines d'un grand objet des arbres?

[Modifier] Ok, j'ai lu les réponses jusqu'à présent, mais permet simplement de dire que je suis un bon bâtard (ce qui signifie que je suis plus intéressé à apprendre comment utiliser les JHat que de payer pour JProfiler). Aussi JHat est toujours depuis qu'elle est partie du JDK. Sauf si bien sûr il n'y a aucune manière avec JHat mais la force brute, mais je ne peux pas croire que cela peut être le cas.

Aussi, je ne pense pas que je vais être capable de le modifier (ajout de la journalisation de toutes les tailles de carte) et l'exécuter pendant une période suffisamment longue pour moi à l'avis de la fuite.

132voto

Dima Malenko Points 1535

J'ai utiliser l'approche suivante pour trouver les fuites de mémoire en Java. J'ai utilisé jProfiler avec un grand succès, mais je crois que tout outil spécialisé avec des capacités graphiques (les différences sont plus faciles à analyser sous forme graphique) fonctionnera.

  1. Démarrez l'application et attendre jusqu'à ce qu'il arrive à "stable" de l'état, quand tout l'initialisation est terminée et que l'application est inactive.
  2. Exécutez l'opération suspectée de produire une fuite de mémoire à plusieurs reprises pour permettre à tous les caches, DB liées à l'initialisation.
  3. Exécuter GC et de prendre un instantané de la mémoire.
  4. Exécutez de nouveau l'opération. Selon la complexité de l'opération et les tailles des données qui sont traitées opération devrez peut-être installer à plusieurs à plusieurs fois.
  5. Exécuter GC et de prendre un instantané de la mémoire.
  6. Exécuter un diff pour 2 instantanés et de les analyser.

Fondamentalement, l'analyse devrait commencer à partir de plus positif diff par, disons, les types d'objet et de trouver quelles sont les causes de ces objets supplémentaires de bâton de mémoire.

Pour les applications web qui traitent les demandes dans plusieurs threads d'analyse devient plus compliqué, mais néanmoins approche générale s'applique toujours.

J'ai fait un certain nombre de projets visant spécifiquement à réduire l'empreinte mémoire des applications et de cette approche générale avec une application spécifique sur les réglages et les truc a toujours bien fonctionné.

50voto

jwiklund Points 663

Interlocuteur ici, que j'ai à dire l'obtention d'un outil qui ne doit pas prendre 5 minutes pour répondre à toute cliquez sur le rend beaucoup plus facile de trouver d'éventuelles fuites de mémoire.

Puisque les gens sont ce qui suggère plusieurs outils ( j'ai seulement tenté de visual wm depuis que je suis que dans le JDK et JProbe essai ) j'ai pensé proposer un libre / open source outil construit sur la plate-forme Eclipse, la Mémoire de l'Analyseur (parfois citée comme la SÈVE de la mémoire de l'analyseur) disponible sur http://www.eclipse.org/mat/ .

Ce qui est vraiment cool à propos de cet outil est qu'il a indexé les tas de vidage quand j'ai ouvert pour la première fois ce qui lui a permis d'afficher des données, comme la retenue de segment sans attendre 5 minutes pour chaque objet (assez bien l'ensemble des opérations a été de tonnes plus rapide que les autres outils que j'ai essayé).

Lorsque vous ouvrez le vidage de la premier écran affiche un graphique à secteurs avec le plus grand des objets (comptage de retenue de segment de mémoire) et on peut naviguer rapidement vers le bas pour les objets qui sont de grand confort. Il dispose également d'un Trouverez probablement des fuites suspects qui je reccon peut venir dans maniable, mais depuis que la navigation était assez pour moi, je n'ai pas vraiment y entrer.

15voto

erickson Points 127945

Un outil est d'une grande aide.

Cependant, il ya des moments où vous ne pouvez pas utiliser un outil: le tas de vidage est tellement énorme qu'elle bloque l'outil, vous essayez de dépanner une machine dans certains environnement de production auquel vous seul avez accès au shell, etc.

Dans ce cas, il est utile de connaître votre chemin autour de la hprof fichier de vidage.

Regardez pour les SITES de COMMENCER. Ceci vous montre les objets qui l'utilisent le plus de mémoire. Mais les objets ne sont pas regroupés uniquement par le type: chaque entrée comprend également une "trace" de l'ID. Vous pouvez faire une recherche pour que "TRACE nnnn" voir le haut des quelques images de la pile où l'objet a été alloué. Souvent, une fois que je vois où l'objet est alloué, j'ai trouver un bug et je suis fait. Notez également que vous pouvez contrôler le nombre d'images enregistrées dans la pile avec les options à Xrunhprof.

Si vous consultez le site d'allocation, et de ne pas voir quelque chose de mal, vous devez démarrer en arrière chaînage de certains de ces objets vivants à la racine des objets, pour trouver la référence inattendue de la chaîne. C'est là un outil qui aide vraiment, mais vous pouvez faire la même chose en main (bien, avec grep). Ce n'est pas seulement un objet racine (c'est à dire, l'objet n'est pas soumis à la collecte des déchets). Les Threads, les classes, et la pile d'images agir en tant que root objets, et tout ce à quoi ils font référence à fortement n'est pas recouvrable.

Pour faire le chaînage, regardez dans le TAS de VIDAGE de la section pour les entrées avec le mauvais trace id. Cela vous mènera à un OBJ ou ARR entrée, qui montre un identificateur d'objet unique en hexadécimal. Recherche de toutes les occurrences de cet id pour trouver qui a une forte référence à l'objet. Suivez chacun de ces chemins vers l'arrière comme ils le branche jusqu'à ce que vous trouver d'où la fuite est. Voir pourquoi l'outil est donc à portée de main?

Les membres statiques sont un récidiviste de fuites de mémoire. En fait, même sans un outil, il vaut la peine de dépenser quelques minutes à la recherche par le biais de votre code de Carte statique membres. Peut une carte de développer de grandes? Ne jamais nettoyer ses entrées?

5voto

Tnilsson Points 1450

Il existe des outils qui devraient vous aider à trouver votre fuite, comme JProbe, YourKit, AD4J ou JRockit de Contrôle de Mission. Le dernier est celui que je connais le mieux. Tout bon outil doit vous permettre de descendre à un niveau où vous pouvez facilement identifier ce qui les fuites, et où la fuite objets sont alloués.

À l'aide de tables de hachage, Hashmaps ou similaire est l'une des quelques façons que vous pouvez en fait une fuite de mémoire en Java. Si je devais trouver la fuite en main, je ne serait peridically imprimer la taille de mon HashMaps, et à partir de là, trouver celui où j'ai ajouter des éléments et d'oublier de les supprimer.

4voto

Mike Stone Points 21293

Eh bien, il y a toujours la solution tech faible d’ajout d’enregistrement de la taille de vos cartes quand vous les modifier, puis recherchez les journaux pour lesquels les cartes sont développent au-delà d’une taille raisonnable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X