Trouver une fuite de mémoire Java lorsque tous les tas utilisés n'est pas accessible à partir de threads

je cherche une fuite de mémoire potentielle(ou au moins un gaspillage de mémoire) dans un système basé sur Java. La JVM fonctionne avec une taille de tas maximale de 5 Go et une utilisation de tas de 2 à 3 Go est une ligne de base attendue pour l'application. (Il peut y avoir des pics qui sont plus élevés)

dans un scénario de surcharge sur lequel j'enquête, le tas se remplit. L'analyse d'un tas-dump avec L'outil "Eclipse MemoryAnalyzer Tool" montre (sans surprise) que le tas est entièrement utilisé.

MAT montre 2 candidats de fuite potentielle, les deux conservant approximativement 2,5 Go: java.lang.Fil et un objet de domaine du système qui est largement utilisé pendant le traitement des transactions dans le système. Tous ces objets de domaine sont cependant (sans surprise) accessibles à partir des instances Thread. Ces fils traitent les transactions, après tout. Ainsi, les 2,5 Go attribués à java.lang.Le fil est presque entièrement causé par ces objets de domaine. Pas de surprise ici.

liste de l'arborescence des objets tous java.lang.Les instances de Thread et la somme du tas retenu de tous les threads donnent 2,5 Go de tas retenu.

Où dois-je chercher les autres 2,5 Go qui sont nécessaires pour remplir le tas, s'ils ne sont pas accessibles à partir d'une instance de java.lang.Thread? - Il n'y a rien dans le finaliseur file d'attente - Il n'y a pas une quantité significative d'objets inaccessibles en attente de GC

je pense qu'une autre façon de poser cette question Est: "Comment puis-je trouver tous les objets qui ne sont pas accessible depuis une instance de java.lang.Thread? Peut-être une requête OQL? et l'autre question: "Quels types d'Objets sont là, qui ne sont pas accessibles à partir d'une instance de java.lang.Fil à d'autres Objets dans le Finaliseur File d'attente et les objets non référencés dans l'attente de GC?"

21
demandé sur VoidPointer 2013-12-17 18:59:43

5 réponses

j'ai aussi rencontré le problème avec les fuites de mémoire à notre site,

Utilisez yourkit java profiler qui fournissent beaucoup d'informations et de sa capacité, vous pouvez avoir une plus grande image où toute la mémoire est utilisée.

Vous pouvez trouver un bon tutoriel Trouver Java Fuites De Mémoire avec l'outil au-dessus.

Votre question,

"Quels types d'Objets sont là, qui ne sont pas accessibles à partir d'une instance de Java.lang.Fil à d'autres Objets dans le Finaliseur File d'attente et les objets non référencés dans l'attente de GC?"

il y a quatre types d'objets,

  1. forte accessible, objets qui peuvent être atteints directement via des références à partir d'objets vivants
  2. faible / doux accessible, objets qui ont une référence faible/douce associée à eux
  3. en attente de finalisation, objets en attente de finalisation et dont la référence peut être atteinte par finaliseur la file d'attente
  4. Unreachable ce sont des objets qui ne sont pas accessibles à partir des racines GC, mais qui ne sont pas encore recueillis

en plus de ces JVM utilise également la mémoire Native dont les informations que vous pouvez trouver sur IBM Tas et natif de l'utilisation de la mémoire par la JVM et Merci pour la mémoire et selon YourKit Structure de la mémoire JVM a une mémoire Non-tas dont la définition selon eux est

également, le JVM a une mémoire autre que la mémoire tas, appelée mémoire non tas. Il est créé au démarrage de JVM et stocke les structures par classe telles que le pool des constantes d'exécution, les données de champ et de méthode, et le code pour les méthodes et les constructeurs, ainsi que les chaînes entrelacées.

4
répondu dbw 2013-12-27 04:52:44

comme la mémoire supplémentaire n'apparaît pas dans le tapis, il est difficile de savoir quoi suggérer. Mes excuses si certaines (ou même la plupart) de ces choses sont déjà connues, j'ai juste essayé de rassembler tout ce à quoi je pouvais penser.

FindBugs

FindBugs est un outil d'analyse statique qui balayera votre code à la recherche d'anti-patterns communs et de problèmes et vous donnera un bon rapport sur eux. Il ne ramasser un tas de causes potentielles de la mémoire et des ressources fuite.

décharge manuelle

vous pouvez essayer d'utiliser quelque chose comme JMap ou visualvm pour faire une décharge tas pour l'analyse manuellement et voir si vous obtenez des résultats différents de laisser eclipse le faire:

http://docs.oracle.com/javase/1.5.0/docs/tooldocs/share/jmap.html

http://java.dzone.com/articles/java-heap-dump-are-you-task

Les Anomalies De L'Analyseur

le FAQ sur les analyseurs de mémoire:

http://wiki.eclipse.org/MemoryAnalyzer/FAQ

dit:

symptôme: lors de la surveillance interactive de l'utilisation de la mémoire, la taille du tas utilisé est beaucoup plus grande que ce que rapporte le tapis.

lors de la création de l'index, L'Analyseur de mémoire enlève les objets inaccessibles parce que les divers algorithmes de collecteur d'ordures ont tendance à laisser des ordures derrière (si l'objet est trop petit, se déplacer et réaffecter adresses est-à-cher). Cela ne devrait toutefois pas dépasser 3 à 4%. Si vous voulez savoir quels objets sont supprimés, activez la sortie de débogage comme expliqué ici: MemoryAnalyzer / FAQ#Enable_Debug_Output

une autre raison pourrait être que le tas de déblais n'a pas été écrit correctement. Les VM particulièrement anciennes (1.4, 1.5) peuvent avoir des problèmes si le dump tas est écrit via jmap.

Activation du débogage de sortie vous permettra de voir ce qui s'y passe et confirmer rien de bizarre dans ce domaine.

Certains de ces conseils peuvent être pertinentes

http://eclipsesource.com/blogs/2013/01/21/10-tips-for-using-the-eclipse-memory-analyzer/

3
répondu Tim B 2013-12-23 14:06:53

Utiliser JProfiler et cassez le décompte d'objets tas par classe-trouvez quelle classe a beaucoup d'instances et commencez votre chasse là.

vous pouvez aussi prendre quelques instantanés et comparer les deux dumps tas pour voir quels objets ont été créés pendant cette période. C'est particulièrement pratique si vous savez qu'une certaine action est à l'origine du problème et que vous voulez ignorer tout le bruit d'arrière-plan de L'objet JVM et juste examiner la Delta.

Je l'ai utilisé avec grand succès pour trouver une fuite de mémoire. Ce n'est pas gratuit, mais ça vaut la licence.

1
répondu Bohemian 2013-12-23 15:25:34

peut-être que vous devriez chercher des fuites de mémoire dans le code de connecteur de base de données ou peut-être ORM. Parce que si vous utilisez la bibliothèque raw connection lorsque vous ne fermez pas le curseur, vous pouvez avoir une fuite de mémoire potentielle. Aussi ma deuxième pensée est également liée au connecteur de base de données. Parce que certains d'entre eux (peut-être pas les vôtres) utilise le code natif en dessous et ce est la source de cette fuite. En raison d'une forte utilisation simultanée qui fait sens pour moi. Tu peux vérifier ça si tu veux.

0
répondu bkowalikpl 2013-12-19 22:20:01

Since the extra memory is not showing in MAT it's hard to know what to suggest. Ce n'est pas vrai. Le tapis montre des objets inaccessibles. Il suffit d'aller à de Preferences et de cocher la case permettant ces options. Après le redémarrage de MAT, vous verrez ces objets avec des détails. Bien sûr, roots to GC ne sera pas disponible.

0
répondu Krashan Brahmanjara 2015-12-18 14:37:44