Skip to content

Quick Start

zhenya edited this page Aug 9, 2025 · 19 revisions

Quick Start

This page provides a quick introduction to using Java System Monitor in your applications.

Usage Examples

System Information

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

Lazy Monitoring

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

Background Monitoring

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 monitor

Formatting Utilities

Use 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

Error Handling

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() + "%");

Best Practices

Refresh Period Optimization

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 /proc on 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 overhead

Periodic Reporting

Consider 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.

Clone this wiki locally