Vraag OS-level systeeminformatie opvragen


Ik ben momenteel bezig met het bouwen van een Java-app die uiteindelijk op veel verschillende platforms kan worden uitgevoerd, maar in de eerste plaats varianten van Solaris, Linux en Windows.

Is iemand in staat geweest om met succes informatie te extraheren, zoals de huidige gebruikte schijfruimte, CPU-gebruik en geheugen dat wordt gebruikt in het onderliggende besturingssysteem? Hoe zit het met wat de Java-app zelf verbruikt?

Bij voorkeur zou ik deze informatie graag willen hebben zonder JNI te gebruiken.


218
2017-08-25 01:49


oorsprong


antwoorden:


U kunt wat beperkte geheugeninformatie van de Runtime-klasse krijgen. Het is echt niet precies wat u zoekt, maar ik dacht dat ik het voor de volledigheid zou verstrekken. Hier is een klein voorbeeld. Bewerken: u kunt ook informatie over schijfgebruik verkrijgen van de klasse java.io.File. Het spulruimtegebruik spul vereist Java 1.6 of hoger.

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

192
2017-08-25 02:53



De java.lang.management pakket geeft je veel meer info dan Runtime - het geeft je bijvoorbeeld heap memory (ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()) gescheiden van niet-heap-geheugen (ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage()).

Je kunt ook CPU-gebruik van de processor krijgen (zonder je eigen JNI-code te schrijven), maar je moet de java.lang.management.OperatingSystemMXBean naar een com.sun.management.OperatingSystemMXBean. Dit werkt op Windows en Linux, ik heb het elders niet getest.

Bijvoorbeeld ... roep de get getCpuUsage () -methode vaker aan om meer nauwkeurige metingen te krijgen.

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

92
2017-09-14 23:41



Ik denk dat de beste methode die er is om het te implementeren SIGAR API van Hyperic. Het werkt voor de meeste belangrijke besturingssystemen (bijna alles wat modern is) en is heel gemakkelijk om mee te werken. De ontwikkelaar (s) reageren erg goed op hun forum en mailinglijsten. Ik hou ook van dat het is GPL2  Apache-licentie. Ze bieden ook een heleboel voorbeelden op Java!

SIGAR == Systeeminformatie-, verzamel- en rapportagetool.


40
2017-08-25 02:36



Er is een Java-project dat JNA gebruikt (dus geen native libraries om te installeren) en is in actieve ontwikkeling. Het ondersteunt momenteel Linux, OSX, Windows, Solaris en FreeBSD en biedt informatie over RAM, CPU, batterij en bestandssysteem.


19
2018-06-23 01:17



U kunt informatie op systeemniveau verkrijgen door te gebruiken System.getenv(), het doorgeven van de relevante omgevingsvariabele naam als een parameter. Bijvoorbeeld op Windows:

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

Voor andere besturingssystemen zullen de aanwezigheid / afwezigheid en namen van de relevante omgevingsvariabelen verschillen.


10
2017-08-16 14:31



Bekijk de beschikbare API's in de java.lang.management pakket. Bijvoorbeeld:

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

Er zitten ook nog veel andere nuttige dingen in.


6
2017-08-26 07:09



OSHI-afhankelijkheid toevoegen via maven:

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

Krijg een resterende batterijcapaciteit in percentage:

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

6
2018-04-10 18:01



Voor windows ging ik deze kant op.

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

Hier is de link met details.


6
2018-06-30 15:05



Meestal, om OS-informatie op een laag niveau te krijgen, kunt u OS-specifieke opdrachten aanroepen die u de gewenste informatie geven met Runtime.exec () of bestanden lezen als / proc / * onder Linux.


5
2018-03-24 19:43



CPU-gebruik is niet eenvoudig - java.lang.management via com.sun.management.OperatingSystemMXBean.getProcessCpuTime komt in de buurt (zie Patrick's uitstekende codefragment hierboven), maar merk op dat dit alleen toegang geeft tot de tijd die de CPU in uw proces heeft doorgebracht. het zal je niet vertellen over de CPU-tijd doorgebracht in andere processen, of zelfs over de CPU-tijd die je hebt doorgebracht met het doen van systeemactiviteiten die verband houden met je proces.

ik heb bijvoorbeeld een netwerkintensief Java-proces - het is het enige dat draait en de CPU staat op 99%, maar slechts 55% daarvan wordt gerapporteerd als "CPU processor".

laat me niet eens beginnen met 'load average' omdat het nutteloos is, ondanks dat het het enige cpu-gerelateerde item is op de MX-bean. als de zon in hun gelegenheidswijsheid zoiets als "getTotalCpuTime" heeft blootgelegd ...

voor serieuze CPU-monitoring lijkt SIGAR genoemd door Matt de beste gok.


5
2018-06-02 02:01



Het is nog in ontwikkeling, maar je kunt het al gebruiken jHardware 

Het is een eenvoudige bibliotheek die systeemgegevens scrapt met behulp van Java. Het werkt zowel in Linux als in 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());
//[...]

4
2018-03-02 21:24