2009-06-09 15 views
5

Actualmente estoy recibiendo el tiempo de CPU hilo total utilizando JMX de la siguiente manera:manera eficaz de conseguir tiempo de CPU hilo utilizando JMX

private long calculateTotalThreadCpuTime(ThreadMXBean thread) { 

    long totalTime = 0l; 

    for (ThreadInfo threadInfo : thread.dumpAllThreads(false, false)) 
     totalTime += thread.getThreadCpuTime(threadInfo.getThreadId()); 

    return totalTime; 
} 

A medida que el ThreadMXBean es en realidad un proxy remoto, el rendimiento es terrible , en el orden de magnitud de segundos para esta llamada al método real.

¿Hay una manera más rápida de hacer esto?


actualización: Estoy usando esto para la supervisión del rendimiento. Las mediciones fueron tanto del reloj de pared como de JProfiler, que mostró aproximadamente el 85% del tiempo que pasé en este método. Tengo algunas otras llamadas de MXBean (Runtime, Memory, GC), pero son mucho más baratas. Lo más probable es que todas las llamadas a thread.getThreadCpuTime sean remotas.

Actualización 2: Captura de pantalla JProfiler que muestra los problemas de rendimiento.

alt text

Respuesta

1

Optimizaciones:

  • invocación getThreadCPUTime dentro de un grupo de subprocesos, ya que parece ser la red de ruedas;
  • cada vez que se encuentre un hilo en Thread.STATE.TERMINATED, mantenga su nombre en un mapa y omita las consultas la próxima vez.
0

Se puede hablar más acerca de cómo usted está planeando sobre el uso de esta información? Puede obtener tiempos de CPU de subprocesos utilizando un agente basado en JVMTI, que debe funcionar un poco mejor que JMX. ¿Cómo ha medido la sobrecarga del enfoque JMX que lo llevó a la conclusión de un rendimiento "terrible"?

+0

Estoy usando esto para el control del rendimiento. Las mediciones fueron tanto del reloj de pared como de JProfiler, que mostró aproximadamente el 85% del tiempo que pasé en este método. Tengo algunas otras llamadas de MXBean (Runtime, Memory, GC), pero son mucho más baratas. –

3

Si usted está dispuesto a utilizar las API no estándar, puede convertir a OperatingSystemMXBeancom.sun.management.OperatingSystemMXBean e invocar getProcessCpuTime(), como se describe en Using a Sun internal class to get JVM CPU time en el blog de David Robert Nadeau.

+0

Gracias por la respuesta. No es ideal, pero lo intentaré. –

2

El problema es la naturaleza remota de sus llamadas.

Recientemente hice un pico al pedir un hilo para los usos de tiempo de CPU y fue increíblemente más rápido. En el contexto de una solicitud de aplicación web, fue casi inconmensurable. Si uno entra en un ciclo difícil, le costará, pero normalmente lo quiere al comienzo de una operación y nuevamente al final.

+0

Correcto, en la misma JVM debería ser barato pero lo estoy haciendo a través de RMI. –

1

La causa del bajo rendimiento es que cada llamada de thread.getThreadCpuTime() (en su caso de un proxy remoto) probablemente resultará en una llamada RMI/Remote JMX que, por supuesto, es costosa, especialmente cuando el mensaje se envía a través de TCP (y tal vez incluso fuera del localhost). (see JMX 1.4 spec, chapter 7.3)

Aunque JMX define multiple attribute retrieval a la vez esto no le ayudará a cabo aquí porque thread.getThreadCpuTime(long) no es un atributo JMX sino una invocación de método remoto (y, además, el objeto ThreadInfo en la que los métodos se invoca difiere en cada llamada)

Desafortunadamente, el JMX 1.La especificación 4 no define algo como "invocar múltiples métodos de múltiples objetos y devolver sus valores de retorno". Entonces, al lado de la invocación concurrente (que ahorrará tiempo pero no reducirá el esfuerzo) de estas llamadas, no estoy al tanto de ninguna optimización (compatible) aquí.

Cuestiones relacionadas