-
Notifications
You must be signed in to change notification settings - Fork 0
Quick Start
This page provides a quick introduction to using Java System Monitor in your applications.
Get basic system information using static methods:
out.printf("Available processors: %d%n", SystemMonitor.getAvailableProcessors());
out.printf("Available memory: %d bytes%n", SystemMonitor.getAvailableMemory());
out.printf("OS name: %s%n", SystemMonitor.getOperatingSystemName());
out.printf("OS version: %s%n", SystemMonitor.getOperatingSystemVersion());
out.printf("JVM name: %s%n", SystemMonitor.getJVMName());
out.printf("JVM vendor: %s%n", SystemMonitor.getJVMVendor());
out.printf("Supported Java version: %s%n", SystemMonitor.getSupportedJavaVersion());
out.printf("Supported system-wide CPU metrics: %s%n", SystemMonitor.isSystemCpuUsageSupported());Example output:
Available processors: 8
Available memory: 15246819328
OS name: Windows 10
OS version: 10.0
JVM name: Java HotSpot(TM) 64-Bit Server VM
JVM vendor: Oracle Corporation
Supported Java version: 1.8
Supported system-wide CPU metrics: true
LazySystemMonitor refreshes usage metrics on demand for applications that need periodic monitoring with minimal overhead:
// Create a lazy monitor with 1-second refresh threshold
try (final SystemMonitor monitor = LazySystemMonitor.withRefreshThreshold(Duration.ofSeconds(1))) {
// Get current metrics (will refresh on first call or if the threshold time elapsed)
final CpuUsage cpu = monitor.getCpuUsage();
final MemoryUsage memory = monitor.getMemoryUsage();
out.printf("Process CPU: %.2f%%%n", cpu.getProcessCpuLoad());
out.printf("System CPU: %.2f%%%n", cpu.getSystemCpuLoad());
out.printf("Used memory: %d bytes%n", memory.getUsedMemory());
}BackgroundSystemMonitor uses a daemon background thread to continuously refresh usage metrics:
For applications that need continuous monitoring in the background:
// Create a background monitor that refreshes every second
try (SystemMonitor monitor = BackgroundSystemMonitor
.refreshEvery(Duration.ofSeconds(1))
.start()) { // Don't forget to start() the monitor
...
} // Automatically stops the monitorUse the Formatter class for human-readable output:
import static software.leonov.system.monitor.util.Formatter.*;
CpuUsage cpu = monitor.getCpuUsage();
MemoryUsage memory = monitor.getMemoryUsage();
// Format percentages
System.out.println("CPU: " + formatPercent(cpu.getSystemCpuLoad()));
// Format memory in binary units (1024-based)
System.out.println("Memory: " + formatBinaryBytes(memory.getUsedMemory()));
// Format memory in decimal units (1000-based)
System.out.println("Memory: " + formatDecimalBytes(memory.getUsedMemory()));Example output:
CPU: 23.5%
Memory: 512 MiB
Memory: 537 MB
The library uses negative values to indicate unavailable metrics instead of throwing exceptions. Rarely a negative return value may also indicate that the metric is not ready to report because it has not been initialized.
final CpuUsage cpu = monitor.getCpuUsage();
if (SystemMonitor.isSystemCpuUsageSupported())
System.out.println("System CPU load is not available on this platform");
else if (cpu.getSystemCpuLoad() < 0)
System.out.println("System CPU load not ready");
else
System.out.println("System CPU is: " + cpu.getProcessCpuLoad() + "%");The monitor refresh period should be made as long as possible for your applications. Here's why:
Resource Efficiency:
- Each refresh involves system calls to collect CPU and memory metrics
- More frequent refreshes consume more CPU cycles and system resources
- Longer refresh periods reduce the monitoring overhead on your application
System Impact:
- System monitoring APIs have inherent costs (accessing
/procon Linux, WMI on Windows) - Frequent polling can impact overall system performance
- Background monitoring threads consume scheduler time slices
Practical Guidelines:
// Good - 1-5 second intervals for most applications
BackgroundSystemMonitor.refreshEvery(Duration.ofSeconds(1))
// Better - 10-30 seconds for less critical monitoring
BackgroundSystemMonitor.refreshEvery(Duration.ofSeconds(10))
// Avoid - sub-second intervals unless absolutely necessary
BackgroundSystemMonitor.refreshEvery(Duration.ofMillis(100)) // High overheadConsider implementing periodic reporting that coincides with natural application boundaries, such as task completion or logging intervals:
Task-Based Reporting:
try (SystemMonitor monitor = BackgroundSystemMonitor.refreshEvery(Duration.ofSeconds(5)).start()) {
while (hasMoreTasks()) {
Task task = getNextTask();
// Capture metrics before task
CpuUsage cpuBefore = monitor.getCpuUsage();
MemoryUsage memoryBefore = monitor.getMemoryUsage();
// Execute task
task.execute();
// Report metrics after task completion
CpuUsage cpuAfter = monitor.getCpuUsage();
MemoryUsage memoryAfter = monitor.getMemoryUsage();
logger.info("Task {} - CPU: {:.1f}% -> {:.1f}%, Memory: {} -> {}",
task.getId(),
cpuBefore.getProcessCpuLoad(),
cpuAfter.getProcessCpuLoad(),
formatBinaryBytes(memoryBefore.getUsedMemory()),
formatBinaryBytes(memoryAfter.getUsedMemory()));
}
}Scheduled Reporting:
try (SystemMonitor monitor = LazySystemMonitor.withRefreshThreshold(Duration.ofSeconds(30))) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
// Report every 5 minutes
scheduler.scheduleAtFixedRate(() -> {
CpuUsage cpu = monitor.getCpuUsage();
MemoryUsage memory = monitor.getMemoryUsage();
logger.info("System Status - CPU: avg={:.1f}% max={:.1f}%, Memory: used={} max={}",
cpu.getAverageProcessCpuLoad(),
cpu.getMaxProcessCpuLoad(),
formatBinaryBytes(memory.getUsedMemory()),
formatBinaryBytes(memory.getMaxUsedMemory()));
}, 5, 5, TimeUnit.MINUTES);
// Your application logic here
scheduler.shutdown();
}Integration with Application Logging:
// Add monitoring to your existing log statements
logger.info("Processing batch {} - Current memory usage: {}",
batchId,
formatBinaryBytes(monitor.getMemoryUsage().getUsedMemory()));
// Include metrics in error reporting
try {
processLargeDataset();
} catch (OutOfMemoryError e) {
MemoryUsage memory = monitor.getMemoryUsage();
logger.error("OOM during processing - Memory: used={} max={} available={}",
formatBinaryBytes(memory.getUsedMemory()),
formatBinaryBytes(memory.getMaxUsedMemory()),
formatBinaryBytes(SystemMonitor.getAvailableMemory()), e);
throw e;
}This approach provides valuable insights into your application's resource usage patterns while minimizing monitoring overhead.