理解 FreeBSD 記憶體報告與 ZFS ARC 快取
理解 FreeBSD 記憶體報告與 ZFS ARC 快取
FreeBSD 記憶體報告的差異
FreeBSD 的記憶體報告在不同系統監控工具之間常常顯得不一致,因為每個工具使用不同的啟發式方法來定義「已使用」與「可用」記憶體。這主要是由於作業系統管理其虛擬記憶體(VM)系統的方式,以及它如何利用 RAM 進行磁碟快取以最佳化效能。
在 FreeBSD 中,記憶體被分為多個頁佇列:
- Active:目前正被使用者程式使用的頁面。
- Inactive:一段時間未被存取的頁面;這些頁面可被回收,若系統需要更多記憶體時可以釋放。
- Laundry:排隊等待寫入交換空間的頁面。
- Wired:核心或被鎖定的程式使用的記憶體,無法換出。此類別也包含 ZFS 自適應取代快取(ARC)。
- Free:純粹未使用的記憶體。
由於 Inactive 頁面和部分 Wired 記憶體(例如磁碟快取)可以被核心回收,工具必須決定是否將它們算作「已使用」或「空閒」。
ZFS ARC 在記憶體使用中的角色
ZFS 是大多數現代 FreeBSD 安裝的預設檔案系統,它使用自適應取代快取(ARC)將最近使用的資料存放在 RAM 中。與標準核心快取不同,ARC 繞過傳統的 VM 系統,並存放在「wired」記憶體類別內。
因為 ARC 設計上會在系統需要更多記憶體給應用程式時自動縮小,它實際上是可回收的。然而,如果監控工具僅僅將「active」與「wired」記憶體相加,ARC 快取會讓系統看起來使用了遠超過實際執行程序所需的 RAM。
若要精確追蹤 ARC 使用情況,管理員可以使用 sysctl 查詢特定的核心參數:
kstat.zfs.misc.arcstats.size:目前快取大小。kstat.zfs.misc.arcstats.c_min:最小配置快取大小。kstat.zfs.misc.arcstats.c_max:最大配置快取大小。
工具啟發式分析:btop、fastfetch 與 htop
不同工具使用不同的公式計算記憶體使用,導致在同一台機器上產生相互矛盾的報告。
btop
歷史上,btop 使用簡化的啟發式:used memory = active + wired。此方法在 FreeBSD 上常常不準確,因為它忽略了 ARC 快取的可回收性,也未考慮 Inactive 頁面。
fastfetch
fastfetch 採用較為寬鬆的空閒記憶體定義:free memory = free + inactive + cache。因此,used memory = total - free memory。這通常會提供較為樂觀的可用資源視圖。
htop
htop 通常會分別報告記憶體類別,但計算已使用記憶體的方式為:used memory = wired + active + laundry。
btop 記憶體報告的關鍵錯誤
對 btop 原始碼(src/freebsd/btop_collect.cpp)的研究揭示了兩個影響 FreeBSD 使用者的重大問題:
32 位元整數溢位
btop 將記憶體頁數存放在 u_int(無號 32 位元整數)中。當透過將頁數乘以頁面大小來計算總位元組時,任何超過 4GiB(4,294,967,296 位元組)的值都會發生環繞。例如,系統實際使用 4.42 GiB 記憶體時,可能只會被報告為 422 MiB,原因正是此整數溢位。
舊版快取報告
btop 嘗試從 vm.stats.vm.v_cache_count 取得快取資料。然而,自 FreeBSD 12.0 起,這個 sysctl 參數已成為「相容性虛設」項目,始終回傳 0。實際的快取佇列自 FreeBSD 6.3.0 起就已不存在。
實作正確的記憶體追蹤
為了解決這些差異,記憶體監控工具必須明確考慮 ZFS ARC 與 FreeBSD 緩衝快取(vfs.bufspace)。
修正後的已使用記憶體計算邏輯包括:
- 計算總快取:將
vfs.bufspace與 ARC 快取的可變部分(目前大小減去最小大小)相加。 - 計算原始已使用:將
active與wired記憶體相加。 - 計算實際已使用:從原始已使用記憶體中減去計算出的快取:
usedBytes = (cachedBytes < rawUsed) ? rawUsed - cachedBytes : 0。
這些改進已作為 pull request 提交給 btop、fastfetch(將邏輯擴展至所有支援 ZFS 的系統,包括 Linux 與 NetBSD)以及 htop,以確保在 FreeBSD 生態系統中提供一致且精確的記憶體報告。
摘要: 深入探討為何 FreeBSD 記憶體使用報告在 btop、fastfetch 等工具間會有所差異,重點說明 ZFS 自適應取代快取(ARC)的角色以及報告工具中的整數溢位錯誤。
標題: 理解 FreeBSD 記憶體報告與 ZFS ARC 快取