Getting Started with OSHI
OSHI (Operating System and Hardware Information) is a free, open-source Java library used to retrieve system information like CPU, memory, disk, network, and OS details. It acts as a cross-platform alternative to platform-specific monitoring tools, abstracting away OS-level APIs. Let us delve into understanding how Java OSHI can be used to gather system-level information in a platform-independent way.
1. What is OSHI?
OSHI stands for Operating System and Hardware Information. It leverages Java Native Access (JNA) to interact with native system APIs, allowing it to run seamlessly across multiple operating systems without requiring native code compilation.
1.1 Key Features
OSHI stands out due to its portability, ease of use, and zero reliance on external binaries. Here are some key highlights:
- Cross-platform support for Windows, macOS, Linux, and Solaris
- Pure Java-based implementation using JNA, with no native code required
- Lightweight and easy to integrate into existing Java applications
- Backed by an active community and frequent updates on GitHub
1.2 Advantages
OSHI brings multiple advantages for developers and DevOps engineers working in Java:
- No need for external binaries or platform-specific agents — just add the dependency and start using
- Unified API across platforms, which abstracts away the OS-specific quirks
- Ideal for system monitoring dashboards, logging agents, and health check modules
- Out-of-the-box support for fetching metrics such as CPU usage, memory, disk I/O, and network interfaces
1.3 Limitations
Despite its rich feature set, OSHI has a few limitations that developers should be aware of:
- Performance: May be slower than directly using native platform-specific APIs, due to JNA overhead
- API Variability: Depends on underlying native APIs, which may vary based on OS version and configuration
- Read-only: OSHI primarily provides read-only access to system data (no control operations like restarting services)
1.4 Why Use OSHI for System Monitoring?
OSHI is a go-to choice for developers building cross-platform monitoring solutions in Java. Here’s why:
- Simplicity: Eliminates the need for OS-specific scripts or tools like
top,vmstat, oriostat - Integration: Can be easily embedded into Spring Boot applications, JavaFX dashboards, or CLI-based tools
- Extensibility: Provides detailed information on CPU, memory, disks, network interfaces, processes, sensors, and more
2. Code Example
This section provides a complete walkthrough for integrating the OSHI library into a Java project, including dependency setup, implementation of system monitoring logic, and a breakdown of the resulting output.
2.1 Add Dependency (pom.xml)
To begin using OSHI in your project, you must first add the required dependency to your pom.xml file. This enables Maven to fetch and include the OSHI core library in your build path.
<dependency> <groupId>com.github.oshi</groupId> <artifactId>oshi-core</artifactId> <version>latest__jar__version</version> </dependency>
2.2 Java Code
Once the dependency is added, you can write Java code that leverages OSHI to extract real-time hardware and software metrics. The following code snippet demonstrates how to access and display system information.
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.ComputerSystem;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HWDiskStore;
import oshi.hardware.NetworkIF;
import oshi.hardware.Sensors;
import oshi.software.os.OperatingSystem;
import oshi.software.os.OSProcess;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* OshiSystemMonitor demonstrates how to use the OSHI library to
* retrieve and display detailed system information including
* operating system details, CPU usage, memory statistics,
* disk info, network interfaces, running processes, and sensors data.
*/
public class OshiSystemMonitor {
/**
* Main method to run the system monitoring program.
* It prints the OS and hardware details, CPU usage over 1 second,
* memory usage, disk details, network interface stats,
* running processes, and sensor information.
*
* @param args command-line arguments (not used)
* @throws InterruptedException if thread sleep is interrupted during CPU load calculation
*/
public static void main(String[] args) throws InterruptedException {
// Initialize SystemInfo object to access hardware and OS info
SystemInfo systemInfo = new SystemInfo();
// Retrieve basic operating system and computer system information
OperatingSystem os = systemInfo.getOperatingSystem();
ComputerSystem cs = systemInfo.getHardware().getComputerSystem();
System.out.println("=== Basic System Information ===");
System.out.println("Operating System: " + os);
System.out.println("Manufacturer: " + cs.getManufacturer());
System.out.println("Model: " + cs.getModel());
System.out.println("Serial Number: " + cs.getSerialNumber());
// Retrieve processor info for CPU monitoring
CentralProcessor processor = systemInfo.getHardware().getProcessor();
System.out.println("\n=== CPU Information ===");
System.out.println("CPU: " + processor.getProcessorIdentifier().getName());
// Capture CPU ticks before sleeping to measure CPU load over 1 second
long[] prevTicks = processor.getSystemCpuLoadTicks();
// Pause for 1 second to calculate CPU usage between ticks
TimeUnit.SECONDS.sleep(1);
// Calculate CPU usage percentage between the two sets of ticks
double cpuLoad = processor.getSystemCpuLoadBetweenTicks(prevTicks) * 100;
System.out.printf("CPU Usage: %.2f%%\n", cpuLoad);
// Retrieve memory information to calculate total, used, and free memory
GlobalMemory memory = systemInfo.getHardware().getMemory();
long total = memory.getTotal();
long available = memory.getAvailable();
long used = total - available;
System.out.println("\n=== Memory Information ===");
System.out.println("Total Memory: " + (total / 1024 / 1024) + " MB");
System.out.println("Used Memory: " + (used / 1024 / 1024) + " MB");
System.out.println("Free Memory: " + (available / 1024 / 1024) + " MB");
// Disk Information
System.out.println("\n=== Disk Information ===");
List<HWDiskStore> diskStores = systemInfo.getHardware().getDiskStores();
for (HWDiskStore disk : diskStores) {
System.out.println("Disk Name: " + disk.getName());
System.out.println("Model: " + disk.getModel());
System.out.println("Serial: " + disk.getSerial());
System.out.println("Size: " + (disk.getSize() / 1024 / 1024 / 1024) + " GB");
System.out.println("Reads: " + disk.getReads());
System.out.println("Writes: " + disk.getWrites());
System.out.println("Read Bytes: " + disk.getReadBytes());
System.out.println("Write Bytes: " + disk.getWriteBytes());
System.out.println();
}
// Network Interface Information
System.out.println("\n=== Network Interfaces ===");
List<NetworkIF> networkIFs = systemInfo.getHardware().getNetworkIFs();
for (NetworkIF net : networkIFs) {
net.updateAttributes(); // Refresh interface stats
System.out.println("Name: " + net.getName());
System.out.println("Display Name: " + net.getDisplayName());
System.out.println("MAC Address: " + net.getMacaddr());
System.out.println("IPv4: " + String.join(", ", net.getIPv4addr()));
System.out.println("IPv6: " + String.join(", ", net.getIPv6addr()));
System.out.println("Bytes Sent: " + net.getBytesSent());
System.out.println("Bytes Received: " + net.getBytesRecv());
System.out.println("Packets Sent: " + net.getPacketsSent());
System.out.println("Packets Received: " + net.getPacketsRecv());
System.out.println();
}
// Process Information (top 5 by CPU usage)
System.out.println("\n=== Top 5 Processes by CPU Usage ===");
List<OSProcess> procs = os.getProcesses(5, OperatingSystem.ProcessSort.CPU);
for (OSProcess proc : procs) {
System.out.printf("PID: %d, Name: %s, CPU: %.2f%%, Memory: %d MB\n",
proc.getProcessID(),
proc.getName(),
100d * proc.getProcessCpuLoadCumulative(),
proc.getResidentSetSize() / 1024 / 1024);
}
// Sensors Information
Sensors sensors = systemInfo.getHardware().getSensors();
System.out.println("\n=== Sensors Information ===");
System.out.println("CPU Temperature: " + sensors.getCpuTemperature() + " °C");
System.out.println("CPU Fan Speed: " + sensors.getFanSpeeds()[0] + " RPM (if available)");
System.out.println("CPU Voltage: " + sensors.getCpuVoltage() + " V");
}
}
2.2.1 Code Explanation
The OshiSystemMonitor Java program utilizes the OSHI library to gather and display comprehensive system information in a cross-platform manner. It begins by initializing a SystemInfo object to access hardware and operating system details, then prints basic system data such as the operating system name, manufacturer, model, and serial number. The program monitors CPU usage by capturing CPU ticks before and after a one-second pause, calculating the real-time CPU load percentage. It then fetches memory statistics including total, used, and free memory, converting bytes to megabytes for readability. Disk information is collected by iterating through all physical disk stores, displaying their names, models, serial numbers, sizes, and read/write statistics. Similarly, the network interface section lists all interfaces with their names, MAC addresses, IPv4 and IPv6 addresses, and network traffic details like bytes and packets sent/received, updating the stats before printing. For process monitoring, the program retrieves the top five running processes sorted by CPU usage, showing each process’s ID, name, CPU load, and memory consumption. Finally, it accesses hardware sensors to report CPU temperature, fan speed (if available), and CPU voltage, providing a snapshot of the system’s performance and health in a single run.
2.2.2 Code Output
When the program is executed, it prints out details about the system’s operating system, hardware, CPU utilization, and memory statistics.
=== Basic System Information === Operating System: Windows 11 build 22621 Manufacturer: Dell Inc. Model: XPS 15 9500 Serial Number: ABC123XYZ === CPU Information === CPU: Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz CPU Usage: 12.34% === Memory Information === Total Memory: 16384 MB Used Memory: 7312 MB Free Memory: 9072 MB === Disk Information === Disk Name: \\.\PhysicalDrive0 Model: Samsung SSD 970 EVO 1TB Serial: S3Z6NX0M123456 Size: 931 GB Reads: 123456 Writes: 654321 Read Bytes: 9876543210 Write Bytes: 1234567890 === Network Interfaces === Name: eth0 Display Name: Ethernet Adapter MAC Address: 00-1A-2B-3C-4D-5E IPv4: 192.168.1.10 IPv6: fe80::1a2b:3c4d:5e6f:7a8b Bytes Sent: 1234567 Bytes Received: 7654321 Packets Sent: 12345 Packets Received: 54321 === Top 5 Processes by CPU Usage === PID: 1234, Name: chrome.exe, CPU: 15.67%, Memory: 450 MB PID: 5678, Name: java.exe, CPU: 10.23%, Memory: 1200 MB PID: 9101, Name: explorer.exe, CPU: 5.45%, Memory: 200 MB PID: 1121, Name: code.exe, CPU: 3.89%, Memory: 350 MB PID: 3141, Name: slack.exe, CPU: 2.15%, Memory: 150 MB === Sensors Information === CPU Temperature: 55.0 °C CPU Fan Speed: 1200 RPM (if available) CPU Voltage: 1.2 V
3. Conclusion
OSHI is a powerful and developer-friendly library for retrieving system information in Java. Whether you are building monitoring tools, logging agents, or health check dashboards, OSHI provides all the capabilities to integrate system-level metrics easily. With no native compilation required and strong cross-platform support, OSHI stands out as a reliable tool in the Java ecosystem for system introspection.

