Вопрос

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

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

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

Это было полезно?

Решение

Вы можете получить некоторую информацию об ограниченной памяти из класса 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());
    }
  }
}

Другие советы

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

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

Например ...чаще вызывайте метод get 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();
        }
    }
}

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

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

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

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

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

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

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

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

Здесь связь с подробностями.

Добавьте зависимость 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));
}

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

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

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

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

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

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

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

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

Он все еще находится в разработке, но вы уже можете использовать jАппаратное обеспечение

Это простая библиотека, которая удаляет системные данные с помощью Java.Он работает как в Linux, так и в 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());
//[...]

Если вы используете Jrockit VM, то есть другой способ узнать об использовании ЦП виртуальной машины.Компонент времени выполнения также может обеспечить загрузку процессора на каждый процессор.Я использовал это только в Red Hat Linux для наблюдения за производительностью Tomcat.Чтобы это работало, вам необходимо включить удаленный JMX в catalina.sh.

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

На Windows, вы можете запустить systeminfo команду и получает ее вывод, например, с помощью следующего кода:

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

Один простой способ получить информацию об уровне ОС, который я протестировал на своем Mac, который работает хорошо:

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

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

Эй, вы можете сделать это с помощью интеграции Java/com.Получив доступ к функциям WMI, вы можете получить всю информацию.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top