java memory - obtener información del sistema a nivel del sistema operativo




model management (13)

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();
        }
    }
}

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.


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());
//[...]

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


Puede obtener cierta información de memoria limitada de la clase Runtime. Realmente no es exactamente lo que estás buscando, pero pensé que te lo proporcionaría por completo. Aquí hay 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());
    }
  }
}

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));
}

Para las ventanas me 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 link con detalles.



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.


En Windows , puede ejecutar el comando systeminfo y recuperar su salida, por ejemplo, con el siguiente código:

private static class WindowsSystemInformation
{
    static String get() throws IOException
    {
        Runtime runtime = Runtime.getRuntime();
        Process process = runtime.exec("systeminfo");
        BufferedReader systemInformationReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

        StringBuilder stringBuilder = new StringBuilder();
        String line;

        while ((line = systemInformationReader.readLine()) != null)
        {
            stringBuilder.append(line);
            stringBuilder.append(System.lineSeparator());
        }

        return stringBuilder.toString().trim();
    }
}

Eche un vistazo a las API disponibles en el paquete java.lang.management . Por ejemplo:

  • OperatingSystemMXBean.getSystemLoadAverage()
  • ThreadMXBean.getCurrentThreadCpuTime()
  • ThreadMXBean.getCurrentThreadUserTime()

Hay un montón de otras cosas útiles allí también.


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");

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.


En Windows, encontré la respuesta https://.com/a/13706972/3014879 usando

fileIsLocked = !file.renameTo(file)

lo más útil, ya que evita falsos positivos al procesar archivos protegidos contra escritura.





java memory resources system