top tool explained java linux top-command

tool - Inspección de hilos de Java en Linux con top



top linux tool (9)

Estoy inspeccionando un proceso de Java en Linux utilizando

top -H

Sin embargo, no puedo leer el nombre del hilo en la columna "COMANDO" (porque es demasiado largo). Si utilizo ''c'' para expandir el nombre completo del proceso, aún me queda mucho tiempo para que encaje.

¿Cómo puedo obtener el nombre completo del comando?


¿Aumenta la variable de entorno COLUMNS más información en la pantalla?



Creé un comando tipo "top" específicamente para visualizar subprocesos Java ordenados por uso de CPU y publiqué el código fuente en: https://github.com/jasta/jprocps . La sintaxis de la línea de comandos no es tan rica como la de arriba, pero admite algunos de los mismos comandos:

jtop -n 1

Salida de muestra (mostrando hormiga e IntelliJ en ejecución):

PID TID USER %CPU %MEM THREAD 13480 13483 jasta 104 2.3 main 13480 13497 jasta 86.3 2.3 C2 CompilerThread1 13480 13496 jasta 83.0 2.3 C2 CompilerThread0 4866 4953 jasta 1.0 13.4 AWT-EventQueue-1 12.1.4#IC-129.713, eap:false 4866 14154 jasta 0.9 13.4 ApplicationImpl pooled thread 36 4866 5219 jasta 0.8 13.4 JobScheduler pool 5/8

A partir de esta salida, puedo extraer el seguimiento de pila del subproceso en jconsole o jstack de forma manual y averiguar qué está pasando.


Este script de shell combina el resultado de jstack y top para mostrar los hilos de Java por uso de CPU. Espera un argumento, el usuario de la cuenta que posee los procesos.

Nombre: jstack-top.sh

#!/bin/sh # # jstack-top - join jstack and top to show cpu usage, etc. # # Usage: jstack-top <user> | view - # USER=$1 TOPS="/tmp/jstack-top-1.log" JSKS="/tmp/jstack-top-2.log" PIDS="$(ps -u ${USER} --no-headers -o pid:1,cmd:1 | grep ''bin/java'' | grep -v ''grep'' | cut -d'' '' -f1)" if [ -f ${JSKS} ]; then rm ${JSKS} fi for PID in ${PIDS}; do jstack -l ${PID} | grep "nid=" >>${JSKS} done top -u ${USER} -H -b -n 1 | grep "%CPU/|java" | sed -e ''s/[[:space:]]*$//'' > ${TOPS} while IFS= read -r TOP; do NID=$(echo "${TOP}" | sed -e ''s/^[[:space:]]*//'' | cut -d'' '' -f1) if [ "${NID}" = "PID" ]; then JSK="" TOP="${TOP} JSTACK" else NID=$(printf ''nid=0x%x'' ${NID}) JSK=$(grep "${NID} " ${JSKS}) fi echo "${TOP} ${JSK}" done < "${TOPS}"


Esto podría ser un poco viejo, pero esto es lo que hice para fusionar un poco y apilar juntos. Usé dos scripts, pero estoy seguro de que todo podría hacerse en uno.

Primero, guardo el resultado de la parte superior con los pids para mis hilos java en un archivo y guardo el archivo jstack en otro archivo:

#!/bin/sh top -H -b -n 1 | grep java > /tmp/top.log jstack -l `ps fax | grep java | grep tomcat | sed "s/ */([0-9]*/) .*//1/g"` > /tmp/jstack.log

Luego uso una secuencia de comandos perl para llamar al script bash (llamado cpu-java.sh aquí) y unir los dos archivos (/tmp/top.log y /tmp/jstack.log):

#!/usr/bin/perl system("sh cpu-java.sh"); open LOG, "/tmp/top.log" or die $!; print "PID/tCPU/tMem/tJStack Info/n"; while ($l = <LOG>) { $pid = $l; $pid =~ s/root.*//g; $pid =~ s/ *//g; $hex_pid = sprintf("%#x", $pid); @values = split(//s{2,}/, $l); $pct = $values[4]; $mem = $values[5]; open JSTACK, "/tmp/jstack.log" or die $!; while ($j = <JSTACK>){ if ($j =~ /.*nid=.*/){ if ($j =~ /.*$hex_pid.*/){ $j =~ s//n//; $pid =~ s//n//; print $pid . "/t" . $pct . "/t" . $mem . "/t" . $j . "/n"; } } } close JSTACK; } close LOG;

La salida me ayuda a descubrir qué hilos están acaparando mi CPU:

PID CPU Mem JStack Info 22460 0 8.0 "main" prio=10 tid=0x083cb800 nid=0x57bc runnable [0xb6acc000] 22461 0 8.0 "GC task thread#0 (ParallelGC)" prio=10 tid=0x083d2c00 nid=0x57bd runnable 22462 0 8.0 "GC task thread#1 (ParallelGC)" prio=10 tid=0x083d4000 nid=0x57be runnable 22463 0 8.0 "GC task thread#2 (ParallelGC)" prio=10 tid=0x083d5800 nid=0x57bf runnable 22464 0 8.0 "GC task thread#3 (ParallelGC)" prio=10 tid=0x083d7000 nid=0x57c0 runnable ...

Luego, puedo volver a /tmp/jstack.log y echar un vistazo al seguimiento de la pila para el hilo problemático y tratar de averiguar qué está pasando desde allí. Por supuesto, esta solución depende de la plataforma, pero debería funcionar con la mayoría de los sabores de * nix y algunos ajustes aquí y allá.


Los hilos no tienen nombres en lo que se refiere al kernel; solo tienen números de identificación. La JVM asigna nombres a los hilos, pero eso son datos internos privados dentro del proceso, que el programa "superior" no puede acceder (y de todos modos no conoce).



Puede inspeccionar hilos de Java con la herramienta jstack . Enumerará los nombres, stacktraces y otra información útil de todos los hilos que pertenecen al proceso especificado pid.

Editar : El parámetro nid en el volcado de subprocesos de jstack es la versión hexadecimal del LWP que se muestra arriba en la columna pid para subprocesos.


Una vieja pregunta, pero tenía el mismo problema con la top .

Resulta que puedes desplazar la salida de la parte superior hacia la derecha simplemente usando las teclas cursoras :)

(pero desafortunadamente no se mostrará ningún nombre de hilo)