получить информацию о системе на уровне ОС
Вопрос
В настоящее время я создаю 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, вы можете получить всю информацию.