用 Rust + 原生 Win32 API 實作的單檔記憶體護欄(tray 常駐 GUI)。 當系統實體記憶體使用率超過門檻時,自動以「終止整棵子進程樹」的方式終止最吃記憶體的程式(預設鎖定 AI / llama 類工作負載),記憶體壓力解除後停止介入。
編譯出來的單一可執行檔約 430 KB,無外部執行期相依。
- 滯回式壓力偵測:使用率 ≥ 觸發門檻進入壓力;要低於「恢復門檻」才解除,避免門檻附近反覆震盪。
- 終止吃記憶體的大程式:依「私有記憶體(private commit)」排名選取,每輪最多終止 N 個。
- 樹狀終止(預設):趁目標存活先快照整棵子進程樹,連同後代一併終止;可在設定中關閉退回「只殺目標、失敗才升級」。
- 保護名單:內建最低保障名單(
csrss、lsass、svchost、explorer… 一律不可殺)+ 使用者自訂保護名單;對後代進程同樣套用,並做 PID 重用的影像名稱核對。 - SeDebugPrivilege:以管理員身分執行時嘗試啟用,可終止其他使用者/高權限進程。
- 單例常駐:以
Local\SystemOOMGuardSingleInstance互斥鎖確保單實例,重複啟動會把既有視窗帶到前景。 - 托盤圖示 + 狀態列:即時顯示使用率/可用/門檻與最後動作;支援 explorer 重啟後重建托盤圖示。
- 開機自啟:寫入登入觸發的排程任務;可選擇程式啟動後是否自動啟用護欄。
需要 Windows + Rust(MSVC toolchain)。
cargo build --release產物:target\release\System-OOM-Guard.exe
Release profile 採用
lto = true、codegen-units = 1、panic = "abort"、strip = true,以壓細體積。
- 直接執行:啟動 GUI 常駐;非管理員時會嘗試自我提權(
runas)。 --no-elevate:跳過自我提權(測試/低權限環境用)。--settings:啟動時直接開啟設定視窗。--crashtest:診斷用,故意觸發一次 panic,用來驗證閃退攔截器會寫入crash.log。--watch:探活用(由復活排程工作每分鐘呼叫)。已有實例在跑則安靜退出;沒有則自己成為新實例(被殺後 ≤60 秒復活)。
建議以管理員身分執行,否則終止其他使用者/高權限進程可能失敗。
| 欄位 | 預設 | 說明 |
|---|---|---|
TriggerUsedPercent |
95 | 觸發介入的記憶體使用率門檻(%) |
RecoverUsedPercent |
85 | 低於此值解除壓力(滯回;一律夾在 trigger 內) |
IntervalSec |
5 | 閒置時輪詢間隔(秒);壓力期間改用 500ms 快速輪詢 |
MaxKillPerCycle |
3 | 每輪最多終止幾個進程 |
CooldownSec |
30 | 兩次終止之间的冷卻(秒) |
AiProcessPattern |
llama|python|ollama|studio |
無視窗程式的特徵比對(` |
ProtectedNames |
見內建 | 使用者保護名單 |
AutoStart |
true | 開機自啟(登入排程任務) |
AutoGuard |
true | 程式啟動後自動啟用護欄 |
KillTree |
true | 終止時連帶殺死整棵子進程樹 |
ReviveWatch |
true | 復活探活:每分鐘排程 --watch,被外部終止後 ≤60 秒自動重啟;正常結束會自動移除該排程(可在設定勾選) |
OnDemandDebugPriv |
true | SeDebugPrivilege 僅在終止動作的瞬間啟用、完即釋放;取消勾選則改為護欄常駐持有(相容性最高但最可疑) |
config.json 與 System-OOM-Guard.log 會寫在執行檔所在資料夾(已列入 .gitignore,不提交)。
- 候選需通過:非自身、不在最低保障名單、不在使用者保護名單、非近期已處理、且(有視窗 或 符合 AI 特徵)。
KillTree=true(預設):collect_descendants快照後代 → 逐一終止(跳過受保護者、做 PID 重用影像名稱核對)→ 再終止目標。- 結果型別
KillResult:Killed/AlreadyDead/Pending(要求已送出、拆除中,不阻塞)/Failed。 - 近期已處理 PID 有 30 秒冷卻,避免 zombie/拆除中進程被重複選中。
release 採用 panic = "abort",任何 panic/存取違規/堆疊溢出/OOM 都會讓程式瞬間結束且不經正常清理。為此有兩層攔截:
- Panic 攔截器:安裝於
main最前段,把 panic 的執行緒、訊息、來源檔案:行號附加到crash.log。Windows 下存取違規也會經 panic 機制,故多數硬崩潰都能留下來源。(--crashtest可自測此路徑。) - 執行中 sentinel(
run.pid):啟動寫入目前 PID+啟動時間;正常結束、或收到系統關機/重啟/登出(WM_ENDSESSION)時移除(移除失敗會記錄到crash.log,避免偽裝成閃退)。下次啟動若標記仍殘留,代表上次未正常結束(可能堆疊溢出/OOM/被外部終止等不經 hook 的死法),會同時在System-OOM-Guard.log與crash.log記錄「上次未正常結束」及前次標記。 - 可區分性:正常結束會寫一行「已正常結束(結束程式)」;主視窗每 10 分鐘寫一行「心跳」,把閃退的「最後確認存活」時間縮到分鐘級。若外部以
TerminateProcess終止本程式则完全無痕(不經 hook、不產生 WER),只能靠 sentinel+心跳間接推定。 crash.log、run.pid寫在執行檔資料夾(已列入.gitignore,不提交)。
反外掛多具備核心層權限與 SeDebugPrivilege,可繞過任何用戶態防護——「不被殺」做不到,能做的是不給它動手理由+被殺後自動復活:
- 按需權限:
SeDebugPrivilege只在終止動作的瞬間啟用、完即釋放(常駐持有該權限是高可疑特徵)。 - 保護名單:把你玩的遊戲與其反外掛程序名(例:
bluearchive、grap-core64.aes)加入設定的「受保護進程」——護欄永遠不會殺它們,避免引來核心層反制。(不內建硬編碼,由使用者依自己的遊戲自行維護。) - 復活探活(
ReviveWatch):每分鐘排程工作以--watch探活,被殺 ≤60 秒復活;托盤「結束」正常退出會自動移除此排程,不干預自願退出。排程建立時明確設ExecutionTimeLimit=PT0S(無限期),避免 Task Scheduler 未指定時預設的 72 小時逾時把被收編的常駐實例停掉。
僅支援 Windows(大量使用 Win32/ntdll API)。