2012-10-11 18 views
5

Vorrei creare un thread che tenga traccia dell'utilizzo della memoria e dell'utilizzo della CPU.Generare un dump del thread Java senza riavviare.

Se l'applicazione raggiunge un livello elevato, voglio generare un dump dell'heap o un dump del thread.

Esiste un modo per generare un runtime di dump di thread senza riavviare?

+0

Thread.getAllStackTraces() ti darà la maggior parte di ciò che desideri. Oppure puoi eseguire 'jstack {pid}' come programma esterno. –

+2

Non riesco a pensare a un modo per produrre un dump di thread che richiede un riavvio ....;) –

+0

Thread.dumpStack() ti darà la traccia dello stack per il thread corrente. –

risposta

10

Ecco come lo facciamo a livello di codice: http://pastebin.com/uS5jYpd4

usiamo il JMXThreadMXBean e ThreadInfo classi:

ThreadMXBean mxBean = ManagementFactory.getThreadMXBean(); 
ThreadInfo[] threadInfos = mxBean.getThreadInfo(mxBean.getAllThreadIds(), 0); 
... 

si può anche fare un kill -QUIT pid sotto ~ unix per scaricare le pile allo standard-out . C'è anche jstack per scaricare lo stack di una JVM.

Abbiamo anche un'automazione che scarica la pila se il carico medio della domanda supera una certa soglia:

private long lastCpuTimeMillis; 
private long lastPollTimeMillis; 

public void checkLoadAverage() { 
    long now = System.currentTimeMillis(); 
    long currentCpuMillis = getTotalCpuTimeMillis(); 
    double loadAvg = calcLoadAveragePercentage(now, currentCpuMillis); 
    if (loadAvg > LOAD_AVERAGE_DUMP_THRESHOLD) { 
     try { 
      dumpStack("Load average percentage is " + loadAvg); 
     } catch (IOException e) { 
      // Oh well, we tried 
     } 
    } 
    lastCpuTimeMillis = currentCpuMillis; 
    lastPollTimeMillis = now; 
} 

private long getTotalCpuTimeMillis() { 
    long total = 0; 
    for (long id : threadMxBean.getAllThreadIds()) { 
     long cpuTime = threadMxBean.getThreadCpuTime(id); 
     if (cpuTime > 0) { 
      total += cpuTime; 
     } 
    } 
    // since is in nano-seconds 
    long currentCpuMillis = total/1000000; 
    return currentCpuMillis; 
} 

private double calcLoadAveragePercentage(long now, long currentCpuMillis) { 
    long timeDiff = now - lastPollTimeMillis; 
    if (timeDiff == 0) { 
     timeDiff = 1; 
    } 
    long cpuDiff = currentCpuMillis - lastCpuTimeMillis; 
    double loadAvg = (double) cpuDiff/(double) timeDiff; 
    return loadAvg; 
} 
+0

Grazie mille per la soluzione !! –

0

Sì, è possibile generare il proprio dump di stack utilizzando la gestione incorporata MXBeans. Nello specifico, è possibile ottenere tutti gli attuali ThreadInfos dal ThreadMXBean e scrivere i contenuti nella posizione desiderata.

7

per fare uscire i fili allo standard fuori, si può fare qualcosa di simile

ThreadInfo[] threads = ManagementFactory.getThreadMXBean() 
     .dumpAllThreads(true, true); 
for(final ThreadInfo info : threads) 
    System.out.print(info); 

in Java 6 utilizzando la classe ThreadMXBean. Ma suggerirei di utilizzare la registrazione reale invece dell'output standard.

2

Prova “Kill -quit” process_id es

kill -QUIT 2134 

Questo attiverà il dump del thread senza riavviarlo

+0

Definitivamente il più tratto. E se hai solo un processo java, 'kill -QUIT' pidof java'' farebbe il trucco. – pdeschen

Problemi correlati