редакции Выбор
Сбор системных метрик на Java
Начнём с простого. Нативные возможности — это заложенные в собственный функционал, не привнесенный извне.
Класс Runtime имеет статический метод получения имплементации getRuntime(). В нём интерес представляют такие методы как:
- totalMemory();
- freeMemory();
- maxMemory();
- availableprocessors().
Вывод команд представлен на скриншоте:
Метод exec() позволяет вызвать любую системную утилиту, получить результат в виде байтового потока и анализировать его любыми способами. Как пользоваться, показано ниже на примере простого вызова команды dir.
Помимо Runtime, существует ещё одна возможность — получить параметры процессора, оперативной памяти и т.д. Речь идёт о довольно слабо освещаемом, на мой взгляд, классе OperatingSystemMXBean из пакета com.sun.management.OperatingSystemMXBean. Он интересен тем, что скрыт от прямого использования, и получить его можно через фабрику ManagementFactory. Однако статический метод получения getOperatingSystemMXBean() предоставит лишь базовую реализацию интерфейса OperatingSystemMXBean из стандартного пакета java.lang.management, где практически нет никаких методов. Необходимо сделать cast в класс из пакета sun. Вариации различных методов ниже:
Здесь можно измерить загрузку процессора, получить размер файла подкачки, узнать, сколько свободного места на диске, размер свободной физической памяти, насколько загружен процессор текущим Java-процессом и т.д. Подробности можно посмотреть в документации класса OperatingSystemMXBean.
Ниже пример вывода нескольких команд:
Момент: команда по выводу системной загрузки процессора вернула отрицательное число. Это нормальное поведение, так как JVM не смогла определить подобный параметр (Windows 11 Pro for Workstations). В таких случаях в документации явно указано, что библиотека возвращает отрицательный результат.
Определение оставшегося свободного места на каком-либо диске или точке монтирования в случае Unix-систем можно определить через класс FileSystem из пакета java.nio.file. Этот стандартный класс из пакета ввода-вывода, вошедший в Java ещё в 8-й версии, позволяет из Path-класса получить доступ к дисковому пространству, на который указывает этот path. Ниже в примере показано, как получить доступ к диску и достать необходимую инфомацию о количестве свободного и занятого пространства. Всё довольно очевидно. Сделать Stream из Iterable, как в строке 22, можно с помощью Guava, если Gradle:
То есть видно, что язык Java не обделен функционалом по определению системных параметров.
Сторонние библиотеки
Помимо нативного способа определения метрик, существуют библиотеки и проекты, позволяющие делать те же замеры. Как пример возьмём интересный открытый проект OSHI. На момент написания материала у проекта есть 3,2 тыс. звёзд и 721 fork. Неплохая статистика.
Рассмотрим сбор тех же метрик, но с помощью сторонних библиотек. Устанавливаем в зависимостях библиотеку...
... и начинаем. Базовым классом всех рассмотренных примеров является SystemInfo.class, из которого можно получать конкретные информационные классы.
- OSHI-сбор процессорной загруженности
Для сбора информации по процессору/процессорам необходимо получить экземпляр класса CentralProcessor.class. Принцип сбора информации на следующем скриншоте:
Получаем экземпляр центрального процессора, через заданный период с него собираются метрики временных затрат. На слайде — сбор данных о системной загрузке, однако можно собирать и по процессам. Вывод в дробных числах от 0 до 1 (0 — 100%). Более подробно можно посмотреть тут. Обнуление отрицательных чисел на случай, если операционная система не позволяет собирать метрики и результат — отрицательное число.
- OSHI-сбор загруженности оперативной памяти
Для сбора информации по оперативной памяти необходимо получить экземпляр класса GlobalMemory.class. Принцип сбора информации по «оперативке» представлен ниже:
Вывод производится в байтах. Всё очевидно, и комментировать особо нечего. Более подробно тут.
- OSHI-сбор загруженности дискового пространства
Для сбора информации по дисковому пространству необходимо получить экземпляр класса FileSystem.class. Принцип сбора информации по дискам на скриншоте:
Вывод, как всегда, в байтах. За подробностями API сюда. Тут сразу стоит заметить, что список List
Помимо рассмотренного функционала, в проекте есть ещё много интересного по определению различных метрик как аппаратного, так и программного типа. По этой теме, пожалуй, всё.
Спасибо, всем удачи.