Symptômes

L’application Java fonctionne lentement et finit par ne plus fournir de mémoire suffisante ou bien vous constatez une erreur dans les accès ou dans la console de sortie OutOfMemoryError: Java heap space ou OutOfMemoryError: gc overhead limit exceeded.

Cause

Ces problèmes peuvent avoir de nombreuses causes.

Une cause possible est que l’application Java, dans notre cas, CRX / CQ a démarré à partir de la ligne de commande avec les paramètres de mémoire de Java par défaut. Cela signifie que le paramètre jvm -Xmx n’a pas été spécifié. Le CRX ou CQ nécessite au moins 256 Mo de tas allouées pour fonctionner. Si tel est le cas, commencez à partir de la ligne de commande et assurez-vous que les paramètres de mémoire du tas sont définis. Exemple :

java -Xmx512m -jar *.jar

Si ce n’est pas le cas, votre application peut être en train de conserver trop d’objets sans les libérer pour le nettoyage de la mémoire. Il s’agit d’une fuite de mémoire, consultez ici pour plus d’informations. Consultez la section ci-dessous pour savoir comment analyser les problèmes de mémoire dans les applications Java.

Analyse et solutions

Créer un vidage de tas

Générer un vidage de tas automatique

Pour créer automatiquement un vidage de tas épuisant la capacité de la mémoire, vous pouvez ajouter le paramètre -XX:+HeapDumpOnOutOfMemoryError afin de générer un vidage de tas automatiquement lorsque l’application émet le message d’erreur « mémoire insuffisante ». Par exemple,

java -Xmx256m -XX:+HeapDumpOnOutOfMemoryError -jar *.jar

Cette opération génère un fichier de vidage de tas (java_...hprof) dans le répertoire de travail du processus, chaque fois que le processus Java ne dispose pas de mémoire suffisante. Le processus peut continuer à fonctionner après la génération du vidage de tas. Généralement, un fichier de vidage de tas est suffisant pour analyser le problème.

Remarque : si vous utilisez le script crx-quickstart/server/start pour démarrer votre instance CRX, vous pouvez ensuite ajouter -XX:+HeapDumpOnOutOfMemoryError à la variable CQ_JVM_OPTS. (Assurez-vous que la variable n’est pas non plus commentée). Par exemple :

CQ_JVM_OPTS='-XX:+HeapDumpOnOutOfMemoryError'.

Après avoir ajouté ce paramètre et redémarré l’instance CRX, vérifiez que la nouvelle option jvm est définie. Démarrez à partir de la ligne de commande ps -ef | grep java. Vérifiez ensuite si vous voyez -XX:+HeapDumpOnOutOfMemoryError comme paramètre du processus CRX Java.

Si vous devez spécifier un répertoire différent pour générer le vidage de tas en raison des restrictions d’espace disque, vous pouvez ajouter le paramètre -XX:HeapDumpPath=/path/to/generate/heapdump pour indiquer au jvm l’endroit où placer le fichier.

Consultez ici pour une référence des paramètres jvm liés au débogage.

Générer manuellement un vidage de tas

Sun/Oracle JVM.

Pour générer manuellement un vidage de tas, exécutez la commande suivante, sachant que jmap et jps se trouvent dans le sous-dossier corbeille de votre répertoire personnel de JDK :

  1. Recherchez l’identificateur du processus Java pour lequel vous générez un vidage de tas.
    • Sous Unix ou Linux, procédez avec ps -ef | grep java ou jps -l.
    • Dans Windows ceci peut être effectué en ouvrant le gestionnaire de tâches, appuyez sur les touches Ctrl+Shift+Esc. Puis accédez à View > Select Columns > PID (Identificateur de processus) ou jps -l.
  2. Exécutez la commande jmap ci-dessous. Remplacez /path/to/generate/heapdumpfile.hprof par l’emplacement dans lequel que vous souhaitez générer le fichier de vidage de tas, et remplacez 1234 par l’identificateur du processus que vous avez saisi lors de l’étape précédente.
    jmap -dump:format=b,file=/path/to/generate/heapdumpfile.hprof 1234
    

IBM JVM

Vous devez d’abord modifier les paramètres JVM par défaut concernant les agents de vidage pour générer les vidages corrects sur le signal utilisateur. Il existe plusieurs types de vidages, mais vous avez besoin généralement de l’intégralité du système de vidage pour réaliser une analyse complète de la mémoire. Ajoutez les arguments suivants :

Xdump:heap:opts=PHD+CLASSIC:events=user -Xdump:system:events=user

Cet événement « utilisateur » se produit lorsque JVM reçoit du système d’exploitation le signal SIGQUIT (Linux, AIX®, z/OS®, et i5/OS™) ou SIGBREAK (Windows).

Pour plus d’informations, consultez la documentation du fournisseur ici.

Avertissement : les fichiers de vidage de tas doivent être volumineux et peuvent atteindre la même taille sur le disque que votre configuration de paramètre max heap -Xmx jvm. Assurez-vous d’avoir suffisamment d’espace sur le disque alloué au répertoire dans lequel le fichier de vidage est généré.

Analyser le vidage du tas

L’outil idéal pour analyser des vidages du tas est EclipseMAT (analyseur de mémoire d’Eclipse) : http://www.eclipse.org/mat/

Cet outil ne peut pas analyser des vidages générés IBM JVM. Pour ça, il existe plusieurs possibilités. IBM HeapAnalyzer est idéal pour des vidages du tas dans le PHD ou le format classique.

Pour une analyse de vidage complète du système, utilisez IBM Support Assistant Workbench, avec IBM Monitoring and Diagnostic Tools pour Java – Memory Analyzer version 1.2 installé sur le dessus.

Histogramme du tas.

L’histogramme du tas est une mesure simple du nombre d’objets en direct et de la mémoire utilisés par la classe Java. Malheureusement, selon l’installation Java, les outils requis peuvent ne pas être disponibles ou toujours fonctionnels. Pour créer un histogramme de tas, vous devez d’abord disposer de l’ID de processus du processus Java. Pour l’obtenir, accédez à ps ou (le cas échéant), exécutez :

jps -l

Cet outil Java obtient les ID de processus de tous les processus Java en cours d’exécution. Exemple :

327 3332 sun.tools.jps.Jps 3313 crx-quickstart-....JAR

Exécutez la commande suivante :

jmap -histo 3313

La liste est triée par quantité totale de mémoire requise (à l’exception des objets référencés). Les 20 premières lignes de la sortie sont les plus intéressantes. Exemple de sortie :

la version JVM est 1.5.0_20-141, réitérant au-dessus du tas. Cette opération peut durer un certain temps. Avertissement : ignorer TLAB non valide pour le thread t @ 62211. Avertissement : ignorer TLAB non valide pour le thread t@62467. Description de la classe de nombre de tailles : 10592904 12916 byte[] 10285840 75255 * ConstMethodKlass 6283176 58388 char[] 6042304 14928 int[] 4995752 116201 * SymbolKlass 4220896 75255 * MethodKlass 4196512 6969 * ConstantPoolKlass 2928560 6969 * InstanceKlassKlass 2631008 6066 * ConstantPoolCacheKlass 2395872 149742 org.apache.jackrabbit.core.query.lucene.DocId$PlainDocId 1476008 7003 java.util.HashMap$Entry[] 1396128 58172 java.lang.String 1070232 44593 java.util.HashMap$Entry 753984 10036 short[] 735464 54 org.apache.jackrabbit.core.query.lucene.DocId[] 720192 7502 java.lang.Class 640704 13348 com.day.crx.persistence.tar.index.IndexEntry ...

Informations supplémentaires

Pour vous aider à analyser le problème, nous devons également connaître les informations suivantes :

  • Version de CRX ou de CQ, y compris une liste de tous les numéros de version des correctifs installés.
  • Système d’exploitation, fournisseur de JVM et version.

Références

[1] http://java.sun.com/javase/6/webnotes/trouble/TSG-VM/html/memleaks.html
[2] http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp#DebuggingOptions

Ce produit est distribué sous licence Creative Commons Attribution - Pas d’utilisation commerciale - Partage à l’identique 3.0 non transposé  Les publications Twitter™ et Facebook ne sont pas couvertes par les dispositions Creative Commons.

Mentions légales   |   Politique de confidentialité en ligne