前言¶
在 Windows 上跑 DSH,每次 shell 調用都會拉起一個私有 runner 進程。命令跑完,這個 runner 本該自己退出,但實測它經常留下來:README 記錄的一臺 DSH Desktop 0.2.x 上,一個工作會話裏攢了 8 個,佔 1127 MB,最老的一個已經空轉了四個半小時。@deepseek-ai/dsh-subprocess-local 和 dsh-ops 都沒有暴露 shell 生命週期的設置項,也就是說沒什麼可配置的。cg-shell-janitor 就是針對這個問題的繞開方案,由 DonGeeo87 維護,分類是 admin-security。
下面介紹它的工作方式、配置項和安裝方法。
問題出在哪¶
Windows 上每次 dsh shell 調用都會啓動一個私有 runner:
"DeepSeek Harness.exe" "...\dsh-subprocess-local\lib\runner.js" -- ...\bash.exe -c "<your command>"
這個 runner 持有命令的 Win32 Job。命令結束時它理應通過自己的 poll() 關閉空 Job 並調用 finish(0),實際卻常常繼續存活,持續佔着內存。這正是 cg-shell-janitor 要清理的對象。
核心功能¶
插件每 intervalSeconds 採樣一次,查找 DSH runner 進程,關閉其中確實無事可幹的。關閉 runner 會釋放它持有的 Win32 Job,這與 DSH 自己管理子進程的語義一致。它只在以下條件全部滿足時才動手:
- runner 的父進程仍然是 DSH host 進程。
- runner 沒有活着的子進程,也就是
bash.exe已經退出。 - 它曾經被觀察到的子進程也沒有還活着的,說明它沒有在照看後臺進程。樹在每次採樣時重新學習,所以用
&留下一個 server 的那條命令,它的 runner 仍受保護。 - 它存在的時間超過
idleMinutes。 - 周圍沒有無法歸因的類 daemon 孤兒進程。如果有,插件進入保守模式,本輪什麼都不關。
啓動後的第一次採樣只觀察,不決定,先摸清當前進程樹。插件不刪除任何文件,除了泄漏的 runner 本身,不碰任何進程。
README 給出的實測數據來自同一臺機器、同一會話,第一次真實週期之後:存活 runner 從 8 個(1127 MB)降到 2 個(288 MB,兩個都有正在跑的 shell),空閒內存從 3.37 GB 升到 5.78 GB,總進程數從 298 降到 240。
安裝¶
README 提到兩種途徑:從 dsh-market 目錄一鍵安裝,或者從本地 checkout 安裝。本地安裝命令是:
dsh plugin --profile <your-profile> add <path-to-this-directory>
完成後重啓 harness。
卸載命令:
dsh plugin --profile <your-profile> remove cg-shell-janitor
配置¶
配置寫在 cordis.patch.yml 裏:
| Key | 默認值 | 含義 |
|---|---|---|
enabled |
true |
關閉週期但不卸載插件 |
dryRun |
false |
只記錄將要關閉的進程,不做實際操作 |
intervalSeconds |
180 |
採樣間隔(取值 30–3600) |
idleMinutes |
5 |
關閉前的最短存活時長(取值 1–1440) |
reapOnStartup |
true |
啓動後 20 秒做第一次採樣 |
一個週期大約每三分鐘佔用單核 2 秒,因爲只通過 PowerShell 跑一次 Get-CimInstance 查詢。如果這對你來說也有影響,把 intervalSeconds 調大即可。
日誌寫在 ~/.dsh/shell-janitor.log,按 256 KB 輪轉。
適用場景與注意¶
面向在 Windows 上長時間使用 DSH、被泄漏 runner 累積佔內存困擾的開發者。需要留意幾點:
- 僅限 Windows。 泄漏出在持有 Win32 Job 的 runner 上,其他平臺上插件只記一行日誌不做任何事。
- 這是一個啓發式方案,不是修復。真正的修復在上游:runner 本該自己退出。
- 插件加載前已創建、且 shell 已經退出的 runner,在插件側沒有子進程記錄。它一旦超過
idleMinutes仍會被關閉,因爲條件 5 只攔那些插件完全無法歸因的孤兒進程。 - 如果你刻意從 shell 命令裏保活一個 daemon,而插件從未觀察到那條命令,這個 daemon 只受保守模式保護,而不是精確匹配保護。
插件以當前 dsh 進程的權限運行,安裝前建議先查看它的源碼(README 和 cordis.patch.yml)並確認許可證:MIT。
小結¶
cg-shell-janitor 做的事情很窄:週期性找出 Windows 上已經無事可做卻沒退出的 DSH runner 並關掉,單個約能回收 140 MB。它不能替代上游修復,但在配置項缺位的情況下提供了可用的清理手段。
- 社區目錄頁:https://www.skillhub.cn/plugins/DonGeeo87/cg-shell-janitor
- GitHub:https://github.com/DonGeeo87/cg-shell-janitor