Obtener información del sistema a nivel de sistema operativo

Resuelto Steve M asked hace 16 años • 17 respuestas

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

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

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

Steve M avatar Aug 25 '08 08:08 Steve M
Aceptado

Puede obtener información de memoria limitada de la clase Runtime. Realmente no es exactamente lo que estás buscando, pero pensé en proporcionártelo para que esté completo. He aquí un pequeño ejemplo. Editar: también puede obtener información sobre el uso del disco de la clase java.io.File. El uso del espacio en disco requiere Java 1.6 o superior.

public class Main {
  public static void main(String[] args) {
    /* Total number of processors or cores available to the JVM */
    System.out.println("Available processors (cores): " + 
        Runtime.getRuntime().availableProcessors());

    /* Total amount of free memory available to the JVM */
    System.out.println("Free memory (bytes): " + 
        Runtime.getRuntime().freeMemory());

    /* This will return Long.MAX_VALUE if there is no preset limit */
    long maxMemory = Runtime.getRuntime().maxMemory();
    /* Maximum amount of memory the JVM will attempt to use */
    System.out.println("Maximum memory (bytes): " + 
        (maxMemory == Long.MAX_VALUE ? "no limit" : maxMemory));

    /* Total memory currently available to the JVM */
    System.out.println("Total memory available to JVM (bytes): " + 
        Runtime.getRuntime().totalMemory());

    /* Get a list of all filesystem roots on this system */
    File[] roots = File.listRoots();

    /* For each filesystem root, print some info */
    for (File root : roots) {
      System.out.println("File system root: " + root.getAbsolutePath());
      System.out.println("Total space (bytes): " + root.getTotalSpace());
      System.out.println("Free space (bytes): " + root.getFreeSpace());
      System.out.println("Usable space (bytes): " + root.getUsableSpace());
    }
  }
}
William Brendel avatar Aug 25 '2008 02:08 William Brendel

El paquete java.lang.management le brinda mucha más información que Runtime; por ejemplo, le brindará memoria de montón ( ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()) separada de la memoria que no es de montón ( 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 archivo java.lang.management.OperatingSystemMXBeana un archivo 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();
        }
    }
}
Patrick Wilkes avatar Sep 14 '2008 23:09 Patrick Wilkes

Creo que el mejor método que existe es implementar la API SIGAR de Hyperic . Funciona para la mayoría de los principales sistemas operativos (casi cualquier cosa moderna) y es muy fácil trabajar con él. Los desarrolladores son muy receptivos en sus foros y listas de correo. También me gusta que tiene licencia Apache GPL2 . ¡También proporcionan un montón de ejemplos en Java!

SIGAR == Herramienta de información, recopilación y generación de informes del sistema.

Matt Cummings avatar Aug 25 '2008 02:08 Matt Cummings

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.

  • https://github.com/oshi/oshi
dB. avatar Jun 23 '2010 01:06 dB.

Para Windows fui por este camino.

    com.sun.management.OperatingSystemMXBean os = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();

    long physicalMemorySize = os.getTotalPhysicalMemorySize();
    long freePhysicalMemory = os.getFreePhysicalMemorySize();
    long freeSwapSize = os.getFreeSwapSpaceSize();
    long commitedVirtualMemorySize = os.getCommittedVirtualMemorySize();

Aquí está el enlace con los detalles.

Yan Khonski avatar Jun 30 '2016 15:06 Yan Khonski