Question

Je suis actuellement en train de créer une application Java qui pourrait finir par être exécutée sur de nombreuses plates-formes différentes, mais principalement sur des variantes de Solaris, Linux et Windows.

Quelqu'un a-t-il réussi à extraire des informations telles que l'espace disque actuellement utilisé, l'utilisation du processeur et la mémoire utilisée dans le système d'exploitation sous-jacent ?Qu’en est-il de ce que consomme l’application Java elle-même ?

De préférence, j'aimerais obtenir ces informations sans utiliser JNI.

Était-ce utile?

La solution

Vous pouvez obtenir des informations limitées sur la mémoire à partir de la classe Runtime.Ce n'est vraiment pas exactement ce que vous recherchez, mais j'ai pensé que je le fournirais par souci d'exhaustivité.Voici un petit exemple.Modifier:Vous pouvez également obtenir des informations sur l'utilisation du disque à partir de la classe java.io.File.Les éléments d'utilisation de l'espace disque nécessitent Java 1.6 ou supérieur.

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

Autres conseils

Le java.lang.gestion Le package vous donne beaucoup plus d'informations que Runtime - par exemple, il vous donnera de la mémoire tas (ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()) séparé de la mémoire non tas (ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage()).

Vous pouvez également obtenir l'utilisation du processeur du processus (sans écrire votre propre code JNI), mais vous devez lancer le java.lang.management.OperatingSystemMXBean à un com.sun.management.OperatingSystemMXBean.Cela fonctionne sous Windows et Linux, je ne l'ai pas testé ailleurs.

Par exemple ...appelez la méthode get getCpuUsage() plus fréquemment pour obtenir des lectures plus précises.

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

Je pense que la meilleure méthode consiste à mettre en œuvre le API SIGAR par Hyperic.Il fonctionne pour la plupart des principaux systèmes d'exploitation (presque tout ce qui est moderne) et est très facile à utiliser.Le(s) développeur(s) sont très réactifs sur leur forum et leurs listes de diffusion.J'aime aussi que ce soit GPL2 Licence Apache.Ils fournissent également une tonne d’exemples en Java !

SIGAR == Outil d'informations système, de collecte et de reporting.

Il existe un projet Java qui utilise JNA (donc pas de bibliothèques natives à installer) et est en développement actif.Il prend actuellement en charge Linux, OSX, Windows, Solaris et FreeBSD et fournit des informations sur la RAM, le processeur, la batterie et le système de fichiers.

Vous pouvez obtenir des informations au niveau du système en utilisant System.getenv(), en passant le nom de la variable d'environnement appropriée en tant que paramètre.Par exemple, sous Windows :

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

Pour les autres systèmes d'exploitation, la présence/absence et les noms des variables d'environnement pertinentes seront différents.

Pour Windows, je suis allé par ici.

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

Voici la lien avec des détails.

Ajouter une dépendance OSHI via maven :

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

Obtenez une capacité restante de la batterie en pourcentage :

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

Jetez un œil aux API disponibles dans le java.lang.gestion emballer.Par exemple:

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

Il y a aussi plein d'autres choses utiles là-dedans.

Habituellement, pour obtenir des informations de bas niveau sur le système d'exploitation, vous pouvez appeler des commandes spécifiques au système d'exploitation qui vous donnent les informations souhaitées avec Runtime.exec() ou lire des fichiers tels que /proc/* sous Linux.

L'utilisation du processeur n'est pas simple - java.lang.management via com.sun.management.OperatingSystemMXBean.getProcessCpuTime s'en rapproche (voir l'excellent extrait de code de Patrick ci-dessus), mais notez qu'il ne donne accès qu'au temps passé par le processeur dans votre processus.il ne vous indiquera pas le temps CPU passé dans d'autres processus, ni même le temps CPU passé à effectuer des activités système liées à votre processus.

par exemple, j'ai un processus Java gourmand en réseau - c'est la seule chose en cours d'exécution et le CPU est à 99% mais seulement 55% de celui-ci est signalé comme "CPU du processeur".

ne me lancez même pas sur la "charge moyenne", car elle est presque inutile, bien qu'elle soit le seul élément lié au processeur sur le bean MX.si seulement le soleil, dans sa sagesse occasionnelle, exposait quelque chose comme "getTotalCpuTime"...

pour une surveillance sérieuse du processeur, SIGAR mentionné par Matt semble le meilleur choix.

Il est encore en développement mais vous pouvez déjà l'utiliser jMatériel

Il s'agit d'une simple bibliothèque qui supprime les données système à l'aide de Java.Cela fonctionne sous Linux et 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());
//[...]

Si vous utilisez Jrockit VM, voici un autre moyen d'obtenir l'utilisation du processeur de la VM.Le bean d'exécution peut également vous donner la charge CPU par processeur.Je l'ai utilisé uniquement sur Red Hat Linux pour observer les performances de Tomcat.Vous devez activer la télécommande JMX dans catalina.sh pour que cela fonctionne.

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

Sur Windows, vous pouvez exécuter le systeminfo et récupère sa sortie par exemple avec le code suivant :

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

Un moyen simple qui peut être utilisé pour obtenir des informations sur le niveau du système d'exploitation et que j'ai testé sur mon Mac et qui fonctionne bien :

 OperatingSystemMXBean osBean =
        (OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
    return osBean.getProcessCpuLoad();

Vous pouvez trouver de nombreuses métriques pertinentes du système d’exploitation ici

Hé, vous pouvez le faire avec l'intégration java/com.En accédant aux fonctionnalités WMI, vous pouvez obtenir toutes les informations.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top