java - management - ps eden space




obtener información del sistema a nivel del sistema operativo (10)

Actualmente estoy creando una aplicación Java que podría acabar ejecutándose en muchas plataformas diferentes, pero principalmente variantes de Solaris, Linux y Windows.

¿Alguien ha podido extraer con éxito información como el espacio en disco actual utilizado, la utilización de la CPU y la memoria utilizada en el sistema operativo subyacente? ¿Qué hay de lo que consume la aplicación Java en sí?

Preferiblemente me gustaría obtener esta información sin usar JNI.


Añadir la dependencia de OSHI a través de maven:

<dependency>
    <groupId>com.github.dblock</groupId>
    <artifactId>oshi-core</artifactId>
    <version>2.2</version>
</dependency>

Obtener una capacidad de batería dejada en porcentaje:

SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
for (PowerSource pSource : hal.getPowerSources()) {
    System.out.println(String.format("%n %s @ %.1f%%", pSource.getName(), pSource.getRemainingCapacity() * 100d));
}


El paquete java.lang.management le brinda mucha más información que Runtime; por ejemplo, le proporcionará memoria de almacenamiento dinámico ( ManagementFactory.getMemoryMXBean().getHeapMemoryUsage() ) separada de la memoria no de almacenamiento dinámico ( ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage() ).

También puede obtener el uso de la CPU del proceso (sin escribir su propio código JNI), pero debe convertir el java.lang.management.OperatingSystemMXBean a com.sun.management.OperatingSystemMXBean . Esto funciona en Windows y Linux, no lo he probado en ningún otro lugar.

Por ejemplo ... llame al método get getCpuUsage () con más frecuencia para obtener lecturas más precisas.

public class PerformanceMonitor { 
    private int  availableProcessors = getOperatingSystemMXBean().getAvailableProcessors();
    private long lastSystemTime      = 0;
    private long lastProcessCpuTime  = 0;

    public synchronized double getCpuUsage()
    {
        if ( lastSystemTime == 0 )
        {
            baselineCounters();
            return;
        }

        long systemTime     = System.nanoTime();
        long processCpuTime = 0;

        if ( getOperatingSystemMXBean() instanceof OperatingSystemMXBean )
        {
            processCpuTime = ( (OperatingSystemMXBean) getOperatingSystemMXBean() ).getProcessCpuTime();
        }

        double cpuUsage = (double) ( processCpuTime - lastProcessCpuTime ) / ( systemTime - lastSystemTime );

        lastSystemTime     = systemTime;
        lastProcessCpuTime = processCpuTime;

        return cpuUsage / availableProcessors;
    }

    private void baselineCounters()
    {
        lastSystemTime = System.nanoTime();

        if ( getOperatingSystemMXBean() instanceof OperatingSystemMXBean )
        {
            lastProcessCpuTime = ( (OperatingSystemMXBean) getOperatingSystemMXBean() ).getProcessCpuTime();
        }
    }
}

El uso de la CPU no es sencillo: java.lang.management a través de com.sun.management.OperatingSystemMXBean.getProcessCpuTime se acerca (vea el excelente fragmento de código de Patrick arriba) pero tenga en cuenta que solo da acceso al tiempo que la CPU pasó en su proceso. no le informará sobre el tiempo de CPU empleado en otros procesos, ni siquiera sobre el tiempo de CPU dedicado a las actividades del sistema relacionadas con su proceso.

por ejemplo, tengo un proceso Java que hace un uso intensivo de la red: es lo único que se está ejecutando y la CPU está al 99%, pero solo el 55% se informa como "CPU del procesador".

ni siquiera me refiero a "cargar promedio", ya que es casi inútil, a pesar de ser el único elemento relacionado con la CPU en el bean MX. si solo el sol en su sabiduría ocasional expusiera algo como "getTotalCpuTime" ...

Para una monitorización seria de la CPU, el SIGAR mencionado por Matt parece la mejor opción.


Hay un proyecto Java que usa JNA (por lo que no es necesario instalar bibliotecas nativas) y está en desarrollo activo. Actualmente es compatible con Linux, OSX, Windows, Solaris y FreeBSD y proporciona información de RAM, CPU, batería y sistema de archivos.


Hey, puedes hacer esto con la integración java / com. Al acceder a las funciones de WMI puede obtener toda la información.


Por lo general, para obtener información del sistema operativo de bajo nivel, puede invocar comandos específicos del sistema operativo que le brinden la información que desea con Runtime.exec () o leer archivos como / proc / * en Linux.


Puede obtener cierta información a nivel del sistema utilizando System.getenv() , pasando el nombre de la variable de entorno relevante como parámetro. Por ejemplo, en Windows:

System.getenv("PROCESSOR_IDENTIFIER")
System.getenv("PROCESSOR_ARCHITECTURE")
System.getenv("PROCESSOR_ARCHITEW6432")
System.getenv("NUMBER_OF_PROCESSORS")

Para otros sistemas operativos, la presencia / ausencia y los nombres de las variables de entorno relevantes serán diferentes.


Si está utilizando Jrockit VM, aquí hay otra forma de obtener el uso de CPU de VM. Runtime bean también puede darle carga de CPU por procesador. He usado esto solo en Red Hat Linux para observar el rendimiento de Tomcat. Debe habilitar el control remoto JMX en catalina.sh para que esto funcione.

JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://my.tomcat.host:8080/jmxrmi");
JMXConnector jmxc = JMXConnectorFactory.connect(url, null);     
MBeanServerConnection conn = jmxc.getMBeanServerConnection();       
ObjectName name = new ObjectName("oracle.jrockit.management:type=Runtime");
Double jvmCpuLoad =(Double)conn.getAttribute(name, "VMGeneratedCPULoad");

Todavía está en desarrollo pero ya puede usar jHardware

Es una biblioteca simple que recorta los datos del sistema usando Java. Funciona tanto en Linux como en Windows.

ProcessorInfo info = HardwareInfo.getProcessorInfo();
//Get named info
System.out.println("Cache size: " + info.getCacheSize());        
System.out.println("Family: " + info.getFamily());
System.out.println("Speed (Mhz): " + info.getMhz());
//[...]




system