cg-shell-janitor:清理 DSH 在 Windows 上遺留的 runner 進程

前言

在 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 自己管理子進程的語義一致。它只在以下條件全部滿足時才動手:

  1. runner 的父進程仍然是 DSH host 進程。
  2. runner 沒有活着的子進程,也就是 bash.exe 已經退出。
  3. 它曾經被觀察到的子進程也沒有還活着的,說明它沒有在照看後臺進程。樹在每次採樣時重新學習,所以用 & 留下一個 server 的那條命令,它的 runner 仍受保護。
  4. 它存在的時間超過 idleMinutes。
  5. 周圍沒有無法歸因的類 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
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜