java jvm cpu-usage visualvm sigar

java - Usando Sigar API para obtener el uso de la CPU JVM



cpu-usage visualvm (1)

Creo que depende de cómo Sigar interprete la información disponible. La información disponible (tiempo de uso de la CPU) se actualiza con ProcCpu frecuencia, y ProcCpu es solo una información de uso de CPU de proceso instantáneo, por eso el uso de CPU para la mayoría de ProcCpu es 0. Nunca los ProcCpu visto, pero para algunos ProcCpu este valor debe ser enormemente superior al 100%.

Puede obtener el uso de la CPU durante un período de tiempo, analizando dos ProcCpu desde el inicio y los momentos finales de la misma, teniendo en cuenta el tiempo de uso de la CPU de ProcCpu (lastTime). Pero recuerde que el valor del tiempo de uso de la CPU no se actualiza con mucha frecuencia, por lo que es posible obtener el mismo tiempo de uso de la CPU para ProcCpu s más de segundo aparte. Para tener información real sobre el uso de la CPU, debes recolectar dos o más ProcCpu s.

Dibujé un monitor que agrega y actualiza información sobre el uso de la CPU:

import java.util.Timer; import java.util.TimerTask; import org.hyperic.sigar.ProcCpu; import org.hyperic.sigar.Sigar; class SigarLoadMonitor { private static final int TOTAL_TIME_UPDATE_LIMIT = 2000; private final Sigar sigar; private final int cpuCount; private final long pid; private ProcCpu prevPc; private double load; private TimerTask updateLoadTask = new TimerTask() { @Override public void run() { try { ProcCpu curPc = sigar.getProcCpu(pid); long totalDelta = curPc.getTotal() - prevPc.getTotal(); long timeDelta = curPc.getLastTime() - prevPc.getLastTime(); if (totalDelta == 0) { if (timeDelta > TOTAL_TIME_UPDATE_LIMIT) load = 0; if (load == 0) prevPc = curPc; } else { load = 100. * totalDelta / timeDelta / cpuCount; prevPc = curPc; } } catch (SigarException ex) { throw new RuntimeException(ex); } } }; public SigarLoadMonitor() throws SigarException { sigar = new Sigar(); cpuCount = sigar.getCpuList().length; pid = sigar.getPid(); prevPc = sigar.getProcCpu(pid); load = 0; new Timer(true).schedule(updateLoadTask, 0, 1000); } public double getLoad() { return load; } }

  • ProcCpu : uso de CPU instantáneo por información de proceso
  • curPc.getTotal() - tiempo total que el proceso usó CPU
  • curPc.getLastTime() - momento en el que ProcCpu representa información
  • El uso de la CPU ( load ) es una relación de tiempo que ese proceso usó la CPU durante algún período ( totalDelta ) y la duración de este período ( timeDelta ).

Si bien las actualizaciones de tiempo de uso de la CPU no son muy frecuentes, he introducido una heurística simple, que supone que la carga es la misma que la anterior, mientras que el tiempo de uso de la CPU no se actualiza. Pero suponiendo que podría ser de carga cero durante un tiempo, introdujo una duración ( TOTAL_TIME_UPDATE_LIMIT ), luego de lo cual el mismo valor de tiempo de uso de la CPU se vuelve legal, y se supone que la carga es realmente cero.

Estoy usando Sigar para obtener el uso de la CPU de la JVM en ejecución actual en un servidor de aplicaciones y almacenarla para una vista histórica de estos datos, pero siempre obtengo un porcentaje de CPU del 0%.

Mientras tanto, mantengo mi visualVM abierto para monitorear el uso de la CPU, y puedo ver que el porcentaje de CPU cambia periódicamente en visualVM, mientras que siempre informa 0% usando Sigar.

Aquí está el código que estoy ejecutando periódicamente:

Sigar sigar = new Sigar(); ProcCpu cpu = null; long pId = sigar.getPid(); // This one gives me the same process ID that I see in visualVM try { cpu = sigar.getProcCpu(pId); } catch (SigarException se) { se.printStackTrace(); } System.out.print(cpu.getPercent());

Este código siempre da 0%.

¿Qué estoy haciendo mal en este caso? ¿Cómo puedo lograr que Sigar muestre el uso de CPU de manera similar al uso que se muestra en VisualVM?

Intenté agregar

cpu.gather(sigar, pId);

después de llamar a getProcCpu (pid), pero sigo obteniendo solo dos valores (0.0 y 9.08729312E-315) incluso si sigo aumentando y disminuyendo la carga en el servidor ...