Question

J'ai été chargé de déboguer une application Java (J2SE) qui, après une période d'activité, commence à générer des exceptions OutOfMemory. Je suis nouveau sur Java, mais j'ai une expérience en programmation. Je souhaiterais connaître votre avis sur ce qu’une bonne approche pour diagnostiquer un problème de ce type pourrait être?

Jusqu'ici, j'ai utilisé JConsole pour avoir une image de ce qui se passe. J'ai l'impression qu'il y a des objets qui ne sont pas libérés correctement et qui ne sont donc pas nettoyés pendant le ramassage des ordures.

Existe-t-il des outils que je pourrais utiliser pour obtenir une image de l'écosystème d'objets? Par où commencerais-tu?

Était-ce utile?

La solution

Je commencerais par un profileur Java approprié. JConsole est gratuit, mais il est loin d'être aussi complet que ceux qui coûtent de l'argent. J'ai utilisé JProfiler, et ça valait bien l'argent. Voir https://stackoverflow.com/questions/14762/please-recommend-a-java-profiler pour plus d'options et d'opinions.

Autres conseils

Essayez le Eclipse Memory Analyzer , ou tout autre outil pouvant traiter un vidage de tas java, puis exécutez votre application avec le volet qui génère un vidage de tas lorsque vous manquez de mémoire.

Ensuite, analysez le vidage de segment de mémoire et recherchez le nombre d'objets suspects.

Consultez cet article pour plus d'informations sur le dump heap .

EDIT: Notez également que votre application peut nécessiter légitimement plus de mémoire que vous ne le pensiez initialement. Vous pouvez essayer d’augmenter d’abord l’allocation de mémoire minimale et maximale de Java à quelque chose de beaucoup plus important et de voir si votre application est exécutée indéfiniment ou si elle est légèrement plus poussée.

La dernière version du JDK Sun inclut VisualVM, qui est essentiellement le profileur Netbeans proprement dit. Cela fonctionne vraiment bien.

http://www.yourkit.com/download/index.jsp est le seul outil dont vous aurez besoin. Vous pouvez prendre des instantanés au (1) moment du début de l'application et (2) après avoir exécuté l'application pendant une période de temps N, puis en comparant les instantanés pour voir où la mémoire est allouée. Il prendra également un instantané sur OutOfMemoryError afin que vous puissiez comparer cet instantané avec (1).

Par exemple, le dernier projet que j'ai eu à résoudre a jeté des exceptions OutOfMemoryError, et après avoir lancé YourKit, j'ai réalisé que la plupart de la mémoire était en fait allouée à un ehcache "LFU". classe, le point étant que nous avons spécifié les charges d’un certain POJO à mettre en mémoire cache, mais que nous ne spécifions pas assez -Xms et -Xmx (allocation de mémoire de démarrage et maximale de JVM).

J'ai également utilisé vmstat de Linux, par exemple. certaines plates-formes Linux n’ont tout simplement pas assez d’échanges swap activés, ou n’allouent pas de blocs de mémoire contigus, et il existe ensuite jstat (fourni avec JDK).

MISE À JOUR voir https://stackoverflow.com/questions/ 14762 / please-recommend-a-java-profiler

Vous pouvez également ajouter un " UnhandledExceptionHandler " au fil de votre application. Cela interceptera l'exception 'non capturée', comme une erreur de mémoire insuffisante, et vous aurez au moins une idée de l'endroit où l'exception a été levée. Habituellement, ce n’est pas le problème mais le «nouveau» qui ne peut pas être satisfait. En règle générale, j'ajoute toujours UnhandledExceptionHandler à un thread, s'il n'y a rien d'autre à ajouter pour la journalisation.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top