2009-05-06 5 views
1

Je suis actuellement à la recherche d'un moyen d'identifier les filets suspendus en java. Quelqu'un sait quelle est la meilleure façon de le faire?Détection automatique des filetages suspendus

Actuellement je pourrais penser de 2 façons de le faire:

  1. appel d'une méthode (de Callback-) périodiquement dans toutes les méthodes de l'application. Cela semble un "peu" complexe et disgracieux ... De plus je n'ai aucun contrôle en appelant des méthodes externes ...
  2. Un Thread supplémentaire qui génère périodiquement Thread-dumps pour tous les Threads (ou peut-être juste pour certains qui devraient être surveillés - comme je sais quel fil je veux surveiller) et analyse le résultat ("le fil est-il toujours au même point avec des verrous sur les mêmes objets", ...). Cela peut être un peu dangereux car le Thread peut de nouveau (!) Être au même point ... En passant - Y at-il un moyen facile d'obtenir le cliché Thread dans Java 1.4 (Je ne veux pas appeler un application externe). Je suppose avec 1.5 ou 1.6 il ya des méthodes pour faire facilement ceci ...

Je suppose que non de ces deux méthodes est une bonne solution ... Alors savez-vous un moyen de faire cela?

Comme je l'ai déjà dit: je ne veux pas utiliser toutes les applications externes ...

+2

On dirait que nous nous approchons dangereusement d'un territoire à problèmes. –

+0

Vraisemblablement, le client devra installer quelque chose - même s'il s'agit d'une nouvelle version de votre code. S'il le fait, pourquoi ne pas ajouter quelques outils supplémentaires? – Pool

+0

Veuillez définir ce que vous voulez dire par "suspendre". Un thread sera en cours d'exécution du code ou en attente. La définition de la pendaison est ambiguë. Comment faites-vous la différence entre un fil supposé être en attente et votre définition de la pendaison? –

Répondre

1

Vous pouvez attacher à un processus en cours d'exécution par l'intermédiaire soit avec jconsole ou jvisualvm. Ces deux outils vous permettront de voir la trace d'une pile de Thread et l'état des threads.

capture d'écran jVisualVM:

JVisualVM monitoring threads

+0

Je pensais que, mais il ne veut pas utiliser d'applications externes ... –

+0

comme je l'ai dit - je ne veux pas utiliser d'applications externes - je maintenant les outils une partie de jdk - mais néanmoins –

+0

Oh, J'ai raté cette partie. Pourquoi pas d'applications externes? –

0

Si vous êtes à la recherche d'une façon "automatique". Il n'y a pas de bonne solution, sauf pour passer plus de temps dans le processus de conception. Si vous avez des threads "suspendus", ils n'ont pas été correctement fermés. Je passerais du temps à regarder comment les fermer contextuellement plutôt que d'essayer d'écrire une routine/thread qui cherche des threads périmés.

+0

pour être sûr que ce serait le meilleur moyen - mais le thread se bloque/bloque dans certaines circonstances lorsque vous essayez d'extraire le résultat de la base de données (comme décrit dans http://download.oracle.com/docs /cd/B14117_01/java.101/b10979/tips.htm#i1001430 sous 28.3.5 - et comme le dit la page: "En raison de limitations dans l'API de thread Java, il n'y a pas de solution de contournement acceptable" ...). le thread attend même la réponse après que le serveur de base de données a fermé la connexion (également mentionné sur le site oracle.com) –

+0

Quelques possibilités me viennent à l'esprit. 1) Je me demande si vous pouvez mettre un délai d'attente sur la connexion au serveur de base de données. Si le temps de réponse est inconnu ou pourrait s'étendre pendant des heures, cela ne fonctionnera pas. 2) L'autre possibilité est de mettre un écouteur sur le thread qui reçoit un message d'un thread minuteur. Lors de la réception de l'événement, le thread pourrait tester la connexion (isAlive, ConnectionStatus, etc ...) et si le thread ne fonctionne toujours pas, appelez la fonction de retrait/close ou similaire. –

0

Ceci est juste une idée:

Conserver dans une information de classe centralisée (synchronisée) sur le temps de démarrage d'un fil et une référence au fil. Dans l'exemple un ConcurrentHashMap (à partir de maintenant CHM).

Passé un certain temps (conservateur), vous pouvez demander à CHM pour ce fil (ou le fil watever que vous suspectez qu'il pourrait être pendu) pour son heure de début. Si le fil est encore en vie, vous pouvez être (conservativement) sûr qu'il est pendu.

Vous pouvez aller plus loin et conserver la pile des threads, comme indiqué précédemment.

+0

semble un peu comme # 1 des façons que j'ai posté, mais encore moins sécurisé ... si je suis conservateur le fil pourrait rester longtemps ... et dans certains cas, la durée d'un tel fil (le fil exécute une sorte de travail) pourrait être très différent ... mais ce serait une solution assez simple ... je vais y réfléchir ... peut-être y a-t-il un moyen facile de le rendre un peu plus "sécurisé" –

+0

Oui , il est basé sur # 1 ... Une autre approche est ce qui est fait dans OpenView ITO, que les paquets keep-alive sont envoyés régulièrement des agents à la "station", mais cette approche nécessite de modifier le code source ... Peut-être que JMX peut vous aider: http://java.sun.com/javase/6/docs/technotes/guides/jmx/overview/JMXoverviewTOC.html – ATorras

2

J'ai découvert que lorsque nous avons des threads bloqués, nous rencontrons généralement un problème de performances sur notre serveur d'applications.

Nous avons un moyen à faible technologie d'essayer de déterminer où les fils sont collés.

Nous envoyons plusieurs signaux kill -3 à la JVM pour générer plusieurs vidages de thread, puis analysons la sortie recherchant des traces similaires, indiquant un code problématique.

Basse technologie et manuel, mais cela a fonctionné.

0

La question ici est de savoir ce que signifie "fil suspendu" et dans quel contexte.

Est-ce qu'il y a un gros serveur J2EE (qui pourrait probablement le découvrir lui-même) ou un petit programme Java où vous multipliez les tonnes de threads? Si c'est le cas, envisagez d'étudier les utilitaires simultanés dans Java 5+, ce qui vous permet de contrôler Runnables et Callables.

0

Si vous avez une condition de course, puis apporter des ressources supplémentaires (c.-à-installer un JDK et en utilisant JPS et jstack) à porter sur le problème est certainement raisonnable ...

Cela dit, si vous utilisez une application En dehors d'un conteneur, vous pouvez simplement lancer l'application depuis la console et appuyer sur ctrl + break (Windows) pour obtenir le vidage du thread. Ou un kill -3 sur * nix. Mais en fonction de vos réponses dans les commentaires, il semble que cela fonctionne probablement dans un serveur d'applications quelconque.

Le problème ici est que presque tout ce que vous faites va introduire une incertitude supplémentaire à la situation. Comment saurez-vous que votre moniteur de blocage n'est pas lui-même responsable des blocages?

Une autre option serait d'introduire la journalisation des entrées du système, puis de créer une nouvelle lecture de ce qui s'est passé dans le système en fonction de ces entrées. Si votre client a essentiellement déclaré qu'il ne vous aidera pas à résoudre votre problème de concurrence, vous devez le trouver vous-même dans votre propre environnement de test. L'émulation des conditions de charge du site client est un moyen d'y parvenir. Mais vraiment, je vous recommande de travailler avec eux pour obtenir un JDK installé (vous pouvez donc utiliser jstack), ou une application de surveillance JRE 1.4 de quelque sorte (assurez-vous que leur serveur d'application ne fournit pas déjà ce genre de chose).

Questions connexes