2012-10-11 100 views
5

Me gustaría crear un hilo que realice un seguimiento del uso de la memoria y el uso de la CPU.Genera un volcado de hilo Java sin reiniciar.

Si la aplicación alcanza un nivel alto, quiero generar un volcado de pila o un volcado de hilo.

¿Hay alguna forma de generar un tiempo de ejecución de volcado de subprocesos sin reiniciar?

+0

Thread.getAllStackTraces() le dará la mayor parte de lo que desee. O puede ejecutar 'jstack {pid}' como un programa externo. –

+2

No puedo pensar en una forma de producir un volcado de hilo que requiera un reinicio ....;) –

+0

Thread.dumpStack() le dará el seguimiento de pila para el hilo actual. –

Respuesta

10

Así es como lo hacemos mediante programación: http://pastebin.com/uS5jYpd4

usamos el JMXThreadMXBean y ThreadInfo clases:

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

También puede hacer un kill -QUIT pid en ~ Unix para volcar las pilas a la norma de salida . También hay jstack para volcar la pila de una JVM.

También tenemos una automatización que vuelca la pila si el promedio de carga de la aplicación está por encima de cierto umbral:

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

¡Muchas gracias por la solución! –

0

Sí, puede generar su propio volcado de pila utilizando la administración integrada de MXBeans. Específicamente, puede obtener todos los ThreadInfos actuales del ThreadMXBean y escribir los contenidos en la ubicación deseada.

7

para volcar los hilos a la salida estándar, es posible hacer algo como esto

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

en Java 6 utilizando la clase ThreadMXBean. Pero sugeriría utilizar el registro real en lugar de la salida estándar.

2

Trate “matar -QUIT” ID_proceso por ejemplo

kill -QUIT 2134 

Este activará el volcado de hilo sin reiniciarlo

+0

Definitivamente el más avanzado. Y si solo tienes un proceso de Java, 'kill -QUIT' pidof java'' haría el truco. – pdeschen

Cuestiones relacionadas