2011-01-21 11 views
32

sto ispezionando un processo Java in Linux utilizzandodiscussioni Ispezione Java in Linux utilizzando top

top -H 

Tuttavia, non riesco a leggere il nome del thread nella colonna "Command" (perché è troppo lungo). Se uso "c" per espandere il nome completo del processo, allora è ancora troppo lungo per adattarsi.

Come posso ottenere il nome completo del comando?

+0

supererà dare informazioni discussioni java ?? –

+0

Questo non è il thread ma il processo. – OscarRyz

+1

@OscarRyz, -H indica i thread in cima all'elenco (nativi). –

risposta

23

È possibile ispezionare i thread java con lo strumento jstack. Elencherà i nomi, gli stacktrack e altre informazioni utili di tutti i thread che appartengono al processo pid specificato.

Modifica: il parametro nid nel dump del thread di jstack è la versione esadecimale del LWP che viene visualizzata nella parte superiore della colonna pid per i thread.

+0

Penso che l'OP significasse processo e non thread – OscarRyz

+2

Penso che intendesse esattamente quello che ha scritto. Ha anche usato -H come parametro per "top" per indicare "top" per visualizzare i thread. –

0

L'aumento della variabile di ambiente COLUMNS fornisce ulteriori informazioni sul display?

+0

Io non la penso così ... c'è una stanza in eccesso sul terminale, ma la colonna COMMAND è troppo stretta. – Jake

+0

Per me il ridimensionamento del terminale Gnome (che probabilmente imposta COLUMNS) andrebbe fatto, ma avrei avuto bisogno di qualcosa come il terminale da 100 "per arrivare alla parte rilevante della riga di comando. – maaartinus

3

I thread non hanno nomi per quanto riguarda il kernel; hanno solo numeri di identificazione. La JVM assegna i nomi ai thread, ma si tratta di dati interni privati ​​all'interno del processo, ai quali il programma "top" non può accedere (e non ne sa comunque).

21

Questo potrebbe essere un po 'vecchio, ma ecco cosa ho fatto per unire un po' top e jstack insieme. Ho usato due script, ma sono sicuro che tutto ciò potrebbe essere fatto in uno.

In primo luogo, salvare l'output dei top con i pid per i miei thread Java in un file e salvare l'output jstack in un altro file:

#!/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 

Poi io uso uno script perl per chiamare lo script bash (chiamato cpu-java.sh qui) e un pò unire i due file (/tmp/top.log e /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; 

L'uscita mi aiuta a scoprire che le discussioni stanno occupando la mia 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 
... 

Quindi posso tornare a /tmp/jstack.log e dare un'occhiata alla traccia dello stack per il thread problematico e cercare di capire cosa sta succedendo da lì. Ovviamente questa soluzione è dipendente dalla piattaforma, ma dovrebbe funzionare con la maggior parte dei tipi di * nix e alcuni tweaking qua e là.

+0

ancora una risposta molto utile, grazie @Andre! – Gregor

11

Ho creato un comando top-like appositamente per visualizzare i thread Java ordinati dall'utilizzo della CPU e pubblicato il codice sorgente a: https://github.com/jasta/jprocps. La sintassi di riga di comando non è così ricco come sopra, ma supporta alcuni degli stessi comandi:

 
jtop -n 1 

Esempio di output (mostrando formica e IntelliJ marcia):

 
    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 

Da questa uscita , Posso tirare manualmente la traccia dello stack del thread in jconsole o jstack e capire cosa sta succedendo.

+0

Freakin fantastico. :) –

+1

provato, ma ottengo KeyError: 'tid' – MitchBroadhead

+0

I get ... "da argparse import ArgumentParser ImportErrore: Nessun modulo denominato argparse" – Amalgovinus

0

Vecchia domanda, ma ho avuto lo stesso problema con top.

Si scopre, è possibile uscita scorrimento di alto a destra semplicemente utilizzando i tasti cursori :)

(ma purtroppo non ci sarà alcuna discussione nome mostrato)

1

Come quanto ho scoperto jstack is outdated a partire dal JDK 8. che cosa ho usato per recuperare tutti i nomi di Java discussione è:

<JDK_HOME>/bin/jcmd <PID> Thread.print 

Controllare jcmd documentation di più.

1

Questo script di shell combina l'output di jstack e top per elencare i thread Java per l'utilizzo della CPU. Si aspetta un argomento, l'utente dell'account che possiede i processi.

Nome: 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}"