75 votes

Comment surveiller l'utilisation de la mémoire de Java ?

Nous avons une application j2ee fonctionnant sur Jboss et nous voulons surveiller son utilisation de la mémoire. Actuellement, nous utilisons le code suivant

    System.gc();
    Runtime rt = Runtime.getRuntime();
    long usedMB = (rt.totalMemory() - rt.freeMemory()) / 1024 / 1024;
    logger.information(this, "memory usage" + usedMB);

Ce code fonctionne bien. Cela signifie qu'il montre une courbe de mémoire qui correspond à la réalité. Lorsque nous créons un gros fichier xml à partir d'une base de données, la courbe monte, puis elle descend une fois l'extraction terminée.

alt text

Un consultant nous a dit qu'appeler gc() explicitement est une erreur, "laissez le jvm décider quand lancer gc". En gros, ses arguments étaient les mêmes que discuté ici . Mais je ne comprends toujours pas :

  • comment puis-je avoir une courbe d'utilisation de la mémoire ?
  • qu'est-ce qui ne va pas avec le gc() explicite ? Je ne me soucie pas des petits problèmes de performance qui peuvent survenir avec la méthode gc() explicite et que j'estimerais à 1-3%. Ce dont j'ai besoin, c'est d'un moniteur de mémoire et de threads qui m'aide à analyser notre système sur le site du client.

1 votes

Surveiller avec jvisualvm - donne de meilleures statistiques.

64voto

amischiefr Points 1799

Si vous voulez vraiment regarder ce qui se passe dans la mémoire de la VM, vous devriez utiliser un bon outil comme VisualVM . C'est un logiciel libre et c'est un excellent moyen de voir ce qui se passe.

Rien n'est vraiment "mauvais" avec explicite gc() appels. Toutefois, n'oubliez pas que lorsque vous appelez gc() vous "suggérez" que le ramasseur de déchets fonctionne. Il n'y a aucune garantie qu'il s'exécutera au moment exact où vous exécutez cette commande.

1 votes

Je viens de regarder VisualVM - c'est génial.

4 votes

System.gc() peut nuire aux performances car il interfère avec les algorithmes du GC. Cela peut dégrader tous les GC suivants.

3 votes

[Vous pouvez démontrer votre affirmation ? Veuillez expliquer comment un appel à gc() "interfère" avec les algorithmes du ramasseur de déchets et comment un appel à une méthode "dégrade" les appels suivants ?

29voto

Il existe des outils qui vous permettent de surveiller l'utilisation de la mémoire de la VM. Le site La VM peut exposer les statistiques de la mémoire en utilisant JMX . Vous pouvez également imprimer les statistiques GC pour voir comment la mémoire se comporte dans le temps.

L'invocation de System.gc() peut nuire aux performances de la GC car les objets seront déplacés prématurément de la nouvelle à l'ancienne génération, et les références faibles seront effacées prématurément. Cela peut entraîner une diminution de l'efficacité de la mémoire, des temps de GC plus longs et une diminution des hits de cache (pour les caches qui utilisent des références faibles). Je suis d'accord avec votre consultant : System.gc() est mauvais. J'irais même jusqu'à le désactiver en utilisant le commutateur de ligne de commande.

12voto

Felix Points 401

Vous pouvez jeter un coup d'œil à moniteur de scène . Il s'agit d'un moniteur de performance d'applications java (web) open source. Il capture les métriques du temps de réponse, les métriques de la JVM, les détails de la requête (y compris une pile d'appels capturée par le profileur de requête) et plus encore. Les frais généraux sont très faibles.

En option, vous pouvez utiliser l'excellente base de données chronologique Graphite pour stocker un long historique de points de données que vous pouvez consulter à l'aide de tableaux de bord sophistiqués.

Ejemplo: JVM Memory Dashboard

Jetez un coup d'œil à la site web du projet pour voir les captures d'écran, les descriptions des fonctionnalités et la documentation.

Note : Je suis le développeur de stagemonitor.

10voto

Yishai Points 42417

Je dirais que le consultant a raison en théorie, et que vous avez raison en pratique. Comme le On dit que :

En théorie, la théorie et la pratique sont identiques. En pratique, elles ne le sont pas.

La spécification Java indique que System.gc suggère d'appeler le garbage collection. En pratique, il crée simplement un thread et s'exécute immédiatement sur la JVM de Sun.

Bien qu'en théorie, vous puissiez perturber une implémentation finement réglée de la collecte des déchets par la JVM, à moins que vous n'écriviez du code générique destiné à être déployé sur n'importe quelle JVM, ne vous en préoccupez pas. Si cela fonctionne pour vous, faites-le.

0 votes

Savez-vous si ce comportement crée un fil de discussion et s'enfuit tout de suite. est également applicable à la JVM (8) actuelle (Sun/Oracle/Hotspot) ?

1 votes

Exécuter System.gc souvent, juste pour obtenir des statistiques sensibles sur l'utilisation de la mémoire, sera blesser les performances. Il ne s'agit donc pas d'un "faites-le". System.gc() est judicieux dans des cas comme "OK, maintenant un gros travail qui nécessitait beaucoup de mémoire est terminé, et je n'ai rien d'autre à faire pour le moment, donc je collecte les ordures pour améliorer les performances des collectes mineures plus tard".

9voto

Tom Points 16783

0 votes

L'ancien lien ne fonctionne plus, il semble que ce soit le lien actuel : oracle.com/ressourcestechniques/articles/java/jconsole.html

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