J'ai une JVM en cours d'exécution avec deux threads. Est-il possible de voir ces threads en cours d'exécution sur mon système d'exploitation Linux avec ps -axl? J'essaie de savoir quelle priorité le système d'exploitation donne à mes threads. Plus d'informations sur cet autre problème ici .
Utilisation
jps -v
pour trouver votre processus Java. Exemple de sortie:
3825 RemoteMavenServer -Djava.awt.headless=true -Xmx512m -Dfile.encoding=MacRoman
6172 AppMain -Didea.launcher.port=7533 -Didea.launcher.bin.path=/Applications/IntelliJ IDEA 10.app/bin -Dfile.encoding=UTF-8
6175 Jps -Dapplication.home=/Library/Java/JavaVirtualMachines/1.6.0_31-b04-411.jdk/Contents/Home -Xms8m
Ensuite, utilisez
jstack 6172
(6172 est l'id de votre processus) pour obtenir une pile de threads à l'intérieur de jvm. La priorité des threads pouvait en être trouvée. Exemple de sortie:
.....
"main" **prio=5** tid=7ff255800800 nid=0x104bec000 waiting on condition [104beb000]
Java.lang.Thread.State: TIMED_WAITING (sleeping)
at Java.lang.Thread.sleep(Native Method)
at au.com.byr.Sample.main(Sample.Java:11)
at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:25)
at Java.lang.reflect.Method.invoke(Method.Java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.Java:120)
.....
Prendre plaisir!
EDIT: Si l'application s'exécute sous un utilisateur différent de vous (cas typique sur la production et d'autres environnements non locaux), alors jps/jstack doit être exécuté via Sudo. Exemples:
Sudo jps -v
Sudo jstack 6172
Sous Linux, la JVM Sun/Oracle implémente Java threads utilisant des threads Linux natifs, donc oui, vous pouvez les voir dans la sortie "ps". Tout thread appartenant à un Java
process est a Java thread. Mais vous ne verrez pas les noms des threads, car ceux-ci sont spécifiques à Java et le système d'exploitation ne les connaît pas).
Les threads Linux ont des ID, mais ce ne sont que des chiffres, et "ps axl" ne les affiche pas. "ps -eLf" le fait, dans la colonne "LWP". ("LWP" est l'abréviation de "processus léger", qui est un autre nom pour un thread.) Dans Java, la méthode Thread.getId()
pourrait retourner le numéro LWP que vous voyez dans " sortie ps -eLf ", mais je ne suis pas sûr.
Toutes les méthodes mentionnées ici fonctionnent très bien. Je cherchais également quelque chose de similaire et je suis tombé sur cela blog par Timur Akhmadeev. J'espère que ça aide.
Éditer:
Comme l'ont souligné mes collègues programmeurs, voici un résumé du message de Timur:
Sur un système basé sur * nux, commencez par
top -H
pour vous montrer l'utilisation du processeur par thread. Recherchez l'utilisateur en tant qu'Oracle et dans la commande en tant que Java. Notez le PID de ce processus, puis exécutez
top -H -p PID
Cela fait apparaître une liste qui affiche toutes les tâches que le processus (programme Java) effectue actuellement. Après cela, nous devons savoir quelle tâche chaque thread peut effectuer, pour laquelle nous utilisons un utilitaire fourni par jdk, à savoir jstack. Sous linux, les threads Java (JVM HotSpot) sont mappés à ceux du kerner.
jstack -pid_of_the_thread
Pour mapper le thread au niveau du système d'exploitation sur un thread Java dans un vidage de thread, nous devons convertir l'ID de thread natif de Linux en base 16 et rechercher "nid = $ ID" dans la trace de la pile. Par exemple, l'ID du thread est 7601 et 0x1db1 peut être celui que vous surveilliez. Si vous souhaitez garder un œil sur ce que le thread peut faire à l'avenir, c'est-à-dire suivre son comportement, il vous suffit d'écrire un script Shell à surveiller. J'espère que cela a du sens.
Le commutateur de sélection de thread ps(1)
H
demandera à ps(1)
d'afficher les threads en tant que processus. (C'est à peu près comment ils sont mis en œuvre de toute façon.)
Voir:
$ ps axl | wc -l
163
$ ps axlH | wc -l
325
Apparemment, j'ai beaucoup de processus filetés en cours d'exécution en ce moment.
Vous pouvez faire un saut JNI dans le code natif pour obtenir le TID natif associé au thread Java particulier. Ensuite, utilisez les commandes du système d'exploitation ou procfs comme d'autres l'ont suggéré ou encore mieux renvoyez les détails du thread jusqu'à Java.
Exemple: code natif
JNIEXPORT jlong JNICALL Java_nativeGetThreadId(JNIEnv * env, jobject obj) {
jlong threadId;
threadId = (jlong)gettid();
return threadId;
}
Si vous avez JDK installé, vous pouvez utiliser un outil appelé jvisualvm pour voir les threads (et effectuer de nombreuses autres opérations relavant à un Java - voir la mémoire, vérification rapide) sur des objets, etc.)