получить системную информацию на уровне ОС - PullRequest
225 голосов
/ 25 августа 2008

В настоящее время я создаю Java-приложение, которое может работать на разных платформах, но в основном это варианты Solaris, Linux и Windows.

Кто-нибудь смог успешно извлечь информацию, такую ​​как текущее используемое дисковое пространство, загрузка ЦП и память, используемая в базовой ОС? Как насчет того, что потребляет само приложение Java?

Желательно, чтобы я получил эту информацию без использования JNI.

Ответы [ 15 ]

196 голосов
/ 25 августа 2008

Вы можете получить ограниченную информацию о памяти из класса Runtime. Это действительно не совсем то, что вы ищете, но я подумал, что предоставлю это для полноты картины. Вот небольшой пример. Изменить: Вы также можете получить информацию об использовании диска из класса java.io.File. Для использования дискового пространства требуется Java 1.6 или выше.

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());
    }
  }
}
93 голосов
/ 15 сентября 2008

Пакет java.lang.management дает гораздо больше информации, чем среда выполнения - например, он даст вам кучную память (ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()) отдельно от не кучной памяти (ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage()) ).

Вы также можете получить нагрузку на процессор (без написания собственного кода JNI), но вам нужно привести java.lang.management.OperatingSystemMXBean к com.sun.management.OperatingSystemMXBean. Это работает на Windows и Linux, я не проверял это в другом месте.

Например ... чаще вызывайте метод getCpuUsage (), чтобы получить более точные показания.

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();
        }
    }
}
40 голосов
/ 25 августа 2008

Я думаю, что лучший способ - реализовать SIGAR API от Hyperic . Он работает для большинства основных операционных систем (чертовски близко ко всему современному) и с ним очень легко работать. Разработчики очень быстро реагируют на свои форумы и списки рассылки. Мне также нравится, что это GPL2 Apache, лицензированный . Они также предоставляют массу примеров на Java!

SIGAR == Инструмент системной информации, сбора и отчетности.

22 голосов
/ 23 июня 2010

Существует проект Java, который использует JNA (поэтому нет собственных библиотек для установки) и находится в активной разработке. В настоящее время он поддерживает Linux, OSX, Windows, Solaris и FreeBSD и предоставляет информацию об оперативной памяти, процессоре, аккумуляторе и файловой системе.

11 голосов
/ 30 июня 2016

Для окон я пошел по этому пути.

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

Вот ссылка с подробностями.

11 голосов
/ 16 августа 2012

Вы можете получить некоторую информацию системного уровня, используя System.getenv(), передав в качестве параметра имя соответствующей переменной среды. Например, в Windows:

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

Для других операционных систем наличие / отсутствие и имена соответствующих переменных среды будут отличаться.

6 голосов
/ 10 апреля 2016

Добавление зависимости OSHI через maven:

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

Получите емкость аккумулятора в процентах:

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 голосов
/ 26 августа 2008

Посмотрите API, доступные в пакете java.lang.management . Например:

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

Там также есть множество других полезных вещей.

5 голосов
/ 02 июня 2009

Использование ЦП не является простым - java.lang.management через com.sun.management.OperatingSystemMXBean.getProcessCpuTime подходит близко (см. Превосходный фрагмент кода Патрика выше), но обратите внимание, что он дает только доступ ко времени, потраченному ЦП в вашем процесс. он не скажет вам о времени ЦП, затраченном на другие процессы, или даже о времени ЦП, затрачиваемом на выполнение системных операций, связанных с вашим процессом.

например, у меня интенсивный сетевой процесс java - он работает только на одном процессоре, и процессор загружен на 99%, но только 55% от этого числа указывается как «процессор процессора».

даже не заставляйте меня начинать с "средней нагрузки", поскольку она почти бесполезна, несмотря на то, что это единственный элемент, связанный с процессором, в компоненте MX. если бы только солнце в их редкой мудрости выставляло что-то вроде "getTotalCpuTime" ...

для серьезного мониторинга процессора SIGAR, упомянутый Мэттом, кажется лучшим выбором.

5 голосов
/ 24 марта 2009

Обычно, чтобы получить информацию об ОС низкого уровня, вы можете вызывать специальные команды ОС, которые предоставляют вам необходимую информацию с помощью Runtime.exec (), или читать файлы, такие как / proc / * в Linux.

...