OSHI簡介
1. 概述
在本教程中,我們將學習一些有趣的內容,以幫助我們了解我們的系統。每當我們考慮在 Java 中檢查 CPU 使用率、記憶體狀態或磁碟空間時,我們可能會問自己, “
我需要呼叫系統命令或使用 JNI 嗎? “
不!這就是 OSHI(作業系統和硬體資訊)的用武之地。
OSHI 是一個純 Java 庫,可以幫助我們獲取系統級詳細信息,而無需任何本機依賴。它充當我們的 Java 應用程式和系統 API 之間的橋樑,以跨平台的方式提取有關作業系統、硬體和網路的有用資訊。
2. 為什麼要使用OSHI進行系統監控?
我們可能會想,「為什麼不直接使用Runtime.exec()
或System.getProperty()
?」嗯,這些方法是有限的。 System.getProperty()
只能取得作業系統名稱和版本,而Runtime.exec()
需要特定於作業系統的指令。
另一方面,OSHI可與最受歡迎的作業系統(Windows、macOS、Linux)相容。它提供有關 CPU、RAM、磁碟、感測器和網路的深度系統洞察。由於它完全基於 Java,因此它不需要本機程式碼,最後但並非最不重要的一點是,它輕量且易於使用——我們只需要添加一個依賴項。
3. 主要特點和優勢
透過 OSHI,我們可以:
- 取得作業系統詳細資訊:名稱、版本、架構和正常運行時間
- 監控 CPU 使用率、核心詳細資訊和處理器速度
- 取得記憶體統計資訊:總 RAM、可用記憶體、交換使用情況
- 檢索磁碟儲存資訊:分割區、讀取/寫入速度
- 追蹤網路介面、IP 位址和頻寬使用情況
- 存取感測器數據,如 CPU 溫度、風扇速度和電壓(如果支援)
現在,讓我們進一步看看如何實現這些功能。
4. 在 Java 專案中設定 OSHI
在我們深入研究有趣的東西之前,讓我們先將 OSHI 加入我們的專案中。
如果我們使用 Maven,我們需要將oshi-core
依賴項新增到我們的pom.xml
中:
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>6.4.2</version>
</dependency>
一旦添加,OSHI 就可以準備推出!
5. 檢索基本系統訊息
現在 OSHI 已經設定好了,讓我們從基礎開始:取得作業系統詳細資訊並檢查系統正常運作時間。
5.1.取得作業系統詳細信息
將我們的作業系統視為機器的大腦。如果知道我們正在運行的是什麼作業系統、哪個版本以及它是 32 位元還是 64 位,那不是很好嗎?
讓我們看看使用 OSHI 可以多麼輕鬆地做到這一點:
@Test
void givenSystem_whenUsingOSHI_thenExtractOSDetails() {
SystemInfo si = new SystemInfo();
OperatingSystem os = si.getOperatingSystem();
assertNotNull(os, "Operating System object should not be null");
assertNotNull(os.getFamily(), "OS Family should not be null");
assertNotNull(os.getVersionInfo(), "OS Version info should not be null");
assertTrue(os.getBitness() == 32 || os.getBitness() == 64, "OS Bitness should be 32 or 64");
}
該程式碼從 OSHI 庫建立一個SystemInfo
物件來存取與系統相關的詳細資訊。然後,它檢索OperatingSystem
實例,該實例提供作業系統系列、版本和位數等資訊。
5.2.檢查系統正常運作時間
有沒有想過我們的系統已經運作多久而不需要重新啟動?系統正常運作時間告訴我們:
@Test
void givenSystem_whenUsingOSHI_thenExtractSystemUptime() {
SystemInfo si = new SystemInfo();
OperatingSystem os = si.getOperatingSystem();
long uptime = os.getSystemUptime();
assertTrue(uptime >= 0, "System uptime should be non-negative");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
fail("Test interrupted");
}
long newUptime = os.getSystemUptime();
assertTrue(newUptime >= uptime, "Uptime should increase over time");
}
在這裡,我們透過建立SystemInfo
物件並存取OperatingSystem
實例來使用 OSHI 檢索系統正常運行時間。測試首先檢查系統正常運作時間是否為非負數,以確保數值有效。然後,它使用Thread.sleep(2000)
暫停兩秒鐘,處理中斷。延遲後,它會再次取得系統正常運作時間,可用於驗證正常運作時間是否隨著時間的推移而增加。
如果我們看到類似3600 seconds
這樣的值,則表示我們的機器已經啟動了一個小時。
6. 使用 OSHI 監控 CPU
CPU(中央處理單元)是任何系統的核心。監控其使用情況、負載和核心數量對於效能調整至關重要。
6.1.取得處理器詳細信息
OSHI 可以使用 Java 輕鬆取得處理器的名稱、核心數量和時脈速度:
@Test
void givenSystem_whenUsingOSHI_thenExtractCPUDetails() {
SystemInfo si = new SystemInfo();
CentralProcessor processor = si.getHardware().getProcessor();
assertNotNull(processor, "Processor object should not be null");
assertTrue(processor.getPhysicalProcessorCount() > 0, "CPU must have at least one physical core");
assertTrue(processor.getLogicalProcessorCount() >= processor.getPhysicalProcessorCount(),
"Logical cores should be greater than or equal to physical cores");
}
此測試初始化一個 來自 OSHI 的SystemInfo
物件並檢索 來自系統硬體的CentralProcessor
實例。這 CentralProcessor
提供有關 CPU 的詳細信息,例如核心數、處理器識別碼和負載指標,但此程式碼片段中不存在任何斷言或驗證。
方法**processor.getPhysicalProcessorCount(
)傳回系統中的物理CPU核心的數量。它確保系統至少有一個物理核心,並且processor.getLogicalProcessorCount()
傳回邏輯處理器的數量,包括超線程核心**。
6.2.動態測量 CPU 負載
如果我們想檢查我們的 CPU 在某個時刻的繁忙程度,我們可以輕鬆地做到這一點:
@Test
void givenSystem_whenUsingOSHI_thenExtractCPULoad() throws InterruptedException {
SystemInfo si = new SystemInfo();
CentralProcessor processor = si.getHardware().getProcessor();
long[] prevTicks = processor.getSystemCpuLoadTicks();
TimeUnit.SECONDS.sleep(1);
double cpuLoad = processor.getSystemCpuLoadBetweenTicks(prevTicks) * 100;
assertTrue(cpuLoad >= 0 && cpuLoad <= 100, "CPU load should be between 0% and 100%");
}
此程式碼捕捉系統的 CPU 負載滴答( prevTicks
),等待一秒鐘,然後使用getSystemCpuLoadBetweenTicks(prevTicks) * 100
計算記錄滴答之間的 CPU 負載百分比。最後,它斷言 CPU 負載在 0% 到 100% 的有效範圍內,確保 OSHI 報告的 CPU 使用率的正確性。
較低的百分比表示我們的 CPU 處於閒置狀態,而較高的百分比表示工作負載較高。
7. 記憶體監控
我們系統的 RAM(隨機存取記憶體)決定了可以同時運行多少個應用程式。
7.1.檢索總 RAM 和可用 RAM
讓我們看看如何檢索系統的總 RAM 和可用 RAM:
@Test
void givenSystem_whenUsingOSHI_thenExtractMemoryDetails() {
SystemInfo si = new SystemInfo();
GlobalMemory memory = si.getHardware().getMemory();
assertTrue(memory.getTotal() > 0, "Total memory should be positive");
assertTrue(memory.getAvailable() >= 0, "Available memory should not be negative");
assertTrue(memory.getAvailable() <= memory.getTotal(), "Available memory should not exceed total memory");
}
程式碼初始化一個SystemInfo
物件並取得GlobalMemory
實例,該實例提供與記憶體相關的資訊。它斷言總記憶體為正,確保系統具有有效的 RAM。它還檢查可用內存是否為非負且不超過總內存,從而驗證 OSHI 的內存報告。
7.2.儲存和磁碟信息
硬碟和 SSD 儲存了我們所有的資料。 OSHI 有助於監控總磁碟空間、分割區和使用情況統計資料:
@Test
void givenSystem_whenUsingOSHI_thenExtractDiskDetails() {
SystemInfo si = new SystemInfo();
List<HWDiskStore> diskStores = si.getHardware().getDiskStores();
assertFalse(diskStores.isEmpty(), "There should be at least one disk");
for (HWDiskStore disk : diskStores) {
assertNotNull(disk.getModel(), "Disk model should not be null");
assertTrue(disk.getSize() >= 0, "Disk size should be non-negative");
}
}
程式碼使用 OSHI 檢索磁碟儲存詳細資訊。它會取得以下列表 HWDiskStore
實例,代表系統磁碟。 它確保至少存在一個磁碟,然後遍歷每個磁碟,驗證模型名稱不為空且磁碟大小非負。這可確保 OSHI 正確偵測並報告磁碟資訊。
8. OSHI 的局限性
儘管 OSHI 功能豐富,但也存在一些限制:
- 感測器數據可用性取決於硬體支援:並非所有機器都公開溫度或電壓讀數
- 有限的低階控制:OSHI 提供唯讀系統洞察;它不允許系統修改
- 對系統 API 的依賴:某些資訊可能因作業系統不同而略有不同
9. 結論
在本文中,我們看到 OSHI 是一個功能強大但輕量級的 Java 函式庫,用於檢索系統和硬體資訊。它消除了處理本機系統命令、JNI 或平台特定依賴項的麻煩,使其成為需要跨平台系統監控的開發人員的絕佳選擇。
與往常一樣,本文中提供的程式碼可在 GitHub 上取得。