web-dev-qa-db-fra.com

Prendre des décharges de fil en production

J'analyse les différences entre les approches pour la prise de décharges de threads. Voici le couple d’entre eux sur lequel je fais des recherches

  1. Définir un bean jmx qui déclenche jstack via Runtime.exec () en cliquant sur une opération de bean déclarée.

  2. Un thread de démon exécutant "ManagementFactory.getThreadMXBean (). DumpAllThreads (true, true)" de manière répétée après un intervalle prédéfini.

En comparant les sorties de vidage de threads entre les deux, je vois les inconvénients ci-dessous avec l'approche 2

  1. Les vidages de threads enregistrés avec l'approche 2 ne peuvent pas être analysés par des analyseurs de vidage de thread open source tels que TDA
  2. La sortie n'inclut pas l'ID de thread natif qui pourrait être utile pour analyser les problèmes de hauts processeurs (non?)
  3. Plus?

J'apprécierais recevoir des suggestions/contributions sur

  1. Existe-t-il des inconvénients à l’exécution de jstack via Runtime.exec () dans le code de production? des problèmes de compatibilité sur différents systèmes d'exploitation - Windows, Linux?

  2. Une autre approche pour prendre des images de thread?

Je vous remercie.

Modifier -  

Une approche combinée de 1 et 2 semble être la voie à suivre. Nous pouvons avoir un thread dédié s'exécutant en arrière-plan et imprimant les dumps de threads dans le fichier journal dans un format compris par les analyseurs de dump de threads . par la sortie jstack, nous le faisons manuellement si nécessaire.

20
Andy Dufresne

Vous pouvez utiliser 

jstack {pid} > stack-trace.log

s'exécutant en tant qu'utilisateur sur la boîte où le processus est en cours d'exécution.

Si vous l'exécutez plusieurs fois, vous pouvez utiliser une diff pour voir plus facilement quels threads sont actifs.


Pour analyser les traces de pile, j’utilise les éléments suivants échantillonnés périodiquement dans un thread dédié.

 Map<Thread, StackTraceElement[]> allStackTraces = Thread.getAllStackTraces();

En utilisant ces informations, vous pouvez obtenir l'ID du thread, son état d'exécution et comparer les traces de la pile.

31
Peter Lawrey

Avec Java 8 en image, jcmd est l'approche recommandée.

jcmd <PID> Thread.print

Voici l'extrait de documentation Oracle :

La version de JDK 8 introduisait Java Mission Control, Java Flight Recorder et l'utilitaire jcmd pour le diagnostic des problèmes liés aux applications JVM et Java. Il est suggéré d'utiliser le dernier utilitaire, jcmd, au lieu du précédent, jstack, pour améliorer les diagnostics et réduire les performances.

Cependant, l'envoi de cette information avec l'application peut entraîner des problèmes de licence, ce dont je ne suis pas sûr.

7
Arnab Biswas

Si c'est un * nix, je voudrais essayer kill -3 <PID>, mais vous devez connaître l'identifiant du processus et vous n'avez peut-être pas accès à la console?

4
Peter Liljenberg

Je vous suggèrerais de procéder à toutes les analyses de tas sur un environnement intermédiaire, le cas échéant, puis de refléter le réglage requis du serveur d'applications sur la production, le cas échéant. Si vous avez besoin des sauvegardes pour analyser l'utilisation de la mémoire de votre application, vous devriez peut-être envisager de la profiler pour une meilleure analyse.

Les vidages de segments de mémoire sont généralement générés à la suite de OutOfMemoryExceptions résultant de fuites de mémoire et d'une mauvaise gestion de la mémoire.

Consultez la documentation de votre serveur d'applications. La plupart des serveurs modernes disposent de moyens permettant de générer des vidages au moment de l'exécution, en plus de la cause normale que j'ai mentionnée précédemment. Le vidage résultant peut toutefois être spécifique au fournisseur.

0
Waleed Madanat