Archive

Posts Tagged ‘diagnostic’

Comment diagnostiquer les problèmes liés aux fuites mémoire avec la plateforme COOX ?

Outils de diagnostic d’une fuite mémoire 

Mémoire
La mémoire est une ressource limitée ! et en java, lorsque la JVM n’a plus assez de mémoire pour s’exécuter, elle génère une Erreur java.lang.OutOfMemoryError.
Plusieurs cas de figure sont alors envisageables :
– Soit vous n’avez pas alloué assez de mémoire à la JVM
– Soit le système a, ce que l’on appelle, une fuite mémoire

Si vous êtes dans le 1er cas, les choses se résolvent assez facilement : il suffit d’allouer plus de mémoire grâce au paramètre -Xmx, et le tour est joué !
Dans le second cas, il va falloir déterminer d’où vient la fuite mémoire.

Mécanisme du ramasse-miettes (Garbage Collector)
Cet élément contribue à la robustesse et à la performance des programmes. Le ramasse-miettes est appelé régulièrement et automatiquement pendant l’exécution du programme.
Sur les systèmes multi-processeurs et/ou multi-cœurs, celui-ci emploie même des threads multiples à faible priorité afin de perturber le moins possible l’exécution de programme.
En outre, le programmeur peut au besoin suggérer de lancer le ramasse-miettes à l’aide de la méthode System.gc().

Un grief récurrent à l’encontre de langages comme C++ est la lourde tâche d’avoir à programmer manuellement la gestion de la mémoire. En C++, la mémoire allouée par le programme pour créer un objet est désallouée lors de la destruction de celui-ci (le plus souvent par un appel explicite à l’opérateur delete). Si le programmeur oublie de coder la désallocation, ceci aboutit à une « fuite mémoire », et le programme en consomme de plus en plus. Pire encore, si par erreur un programme demande plusieurs fois une désallocation, ou emploie une zone de mémoire après avoir demandé sa désallocation, celui-ci deviendra très probablement instable et se plantera.

En Java, une grande partie de ces problèmes est évitée grâce au ramasse-miettes. L’espace mémoire nécessaire à chaque objet créé est alloué dans un tas de mémoire en anglais : memory heap, réservé à cet usage.
Le programme peut ensuite accéder à chaque objet grâce à sa référence dans le tas. Quand il n’existe plus aucune référence permettant d’atteindre un objet, le ramasse-miettes le détruit automatiquement — puisqu’il est devenu inaccessible — libérant la mémoire et prévenant ainsi toute fuite de mémoire.

Le ramasse-miettes emploie un algorithme de marquage puis libération – en anglais –  : mark and sweep qui permet de gérer les cas complexes d’objets se référençant mutuellement ou de boucles de références (cas d’une liste à chaînage double par exemple).
En pratique il subsiste des cas d’erreur de programmation où le ramasse-miettes considèrera qu’un objet est encore utile alors que le programme n’y accèdera plus, mais dans l’ensemble, le ramasse-miettes rend plus simple et plus sûre la destruction d’objets en Java (en supprimant la nécessité de placer au bon endroit du code l’appel à l’opérateur delete).

Diagnostic
Afin de nous aider à analyser et diagnostiquer avec vous les problèmes liés aux fuites mémoire, voici quelques outils à mettre en place qui vous permettront de collecter les informations nécessaires pour cette étude :

  • Le diagnostic tool

La plateforme COOX 7 Helium propose l’outil « Diagnostic tool » pour faciliter la collecte et l’envoi d’informations au support technique. Cet outil peut s’installer sur nimporte quelle machine (voir COOX-DOC-Platform).
Vous pouvez alors nous faire parvenir les éléments lorsque le figeage se produit, en nous précisant la date et l’heure dudit événement.

tool

N’oubliez pas de cocher « collecter le heap dump des serveurs »

Le heap dump des serveurs :
Collecter le heap dump des serveurs revient à exporter le contenu mémoire des JVM des serveurs. Cela permet notamment de diagnostiquer plus facilement les problèmes de débordement mémoire. Toutefois, si cela n’est pas nécessaire, ne le cochez pas systématiquement car les dumps mémoire augmentent grandement le temps de collecte des informations.

  • Heap dump automatique du serveur

Dans le cas où le diagnostic tool n’arrive pas à se connecter au serveur, n’oubliez pas de prendre une capture de la console de cet outil et de nous l’envoyer.
Un autre outil peut être alors utilisé : le dump auto. Le principe consiste à demander à la JVM de faire un Heap dump automatiquement quand on arrive au fameux OutOfMemoryError !
Les deux options à utiliser sont les suivantes :

-XX:+HeapDumpOnOutOfMemoryError : active le dump automatique
-XX:HeapDumpPath : spécifie le fichier d’export

Exemple de modification du fichier manager.properties :
args=-Dswing.aatext\=true -Xmx1G -XX\:PermSize\=256m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:\\tmp\\mydump.hprof -cp .;system\\* globalscreen.startManager

 Cet outil peut être aussi bien utilisé en COOX 6.01, COOX 6.02 qu’en COOX 7 Helium.

  • VisualVM

Visual VM est un outil de monitoring de JVM locale ou distante. Il est intégré au JDK depuis la version 6 update 7. Vous le trouverez dans le répertoire JAVA_HOME/bin/jvisualvm
Il permet notamment :
– de connaître l’occupation CPU, la taille de la heap, le nombre de threads ainsi que le nombre de classes chargées de la JVM. On peut suivre l’évolution dans le temps de ces métriques.
– de réaliser un dump des threads en activité et de la heap.

  1. Faire un Heapdump du poste serveur avec VisualVm au moment du figeage

heapdump

Dans le cas de l’image ci-dessus le poste serveur est le 192.168.0.107

2. Enregistrer des Snapshots

Visualvm permet avec les plugins de prendre des snapshots de la mémoire (avec le graphe de tous les objets)

Génération d’un Snapshot :

snapshot

Exploitation et enregistrement d’un Snapshot :

snapshot1

snapshot2