management eden java memory resources system

eden - java memory model



obtener informaciĆ³n del sistema a nivel del sistema operativo (14)

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

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.



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.


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.


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


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.


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.


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.


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


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