# 記憶體上限規則(必遵守) 本機有一支記憶體守衛 `/root/memkill.py`,每 2 秒掃一次。 **規則:我(opencode)啟動的任何程式,記憶體一律不得超過 80 GiB。** ## 守衛行為 - 觸發條件:`opencode 本體 + 我啟動的所有子行程` 合計 RSS > **80 GiB**(單一子行程 > 64 GiB 也直接砍)。 - 處置:對記憶體最肥的那個子行程樹送 `SIGKILL`(連同它的子行程)。 - **opencode 本體永遠不會被砍**,只砍我開出去的程式。 - 我在 CLI 看到的現象:該指令 exit code 137 / 顯示 `Killed` / 沒有任何輸出。 - 詳細紀錄:`/tmp/memkill.last.json`(最新一次)、`/tmp/memkill.jsonl`(歷史)、`/var/log/memkill.log`(log)。 ```bash cat /tmp/memkill.last.json # 被砍的是哪條指令、峰值多少 GiB ``` ## 被砍之後我必須做的事(順序不可變) 1. **絕對不要用同一種做法重跑一次。** 那是確定會再被砍一次。 2. 先讀 `/tmp/memkill.last.json` 確認峰值用量與被砍的指令。 3. 改用低記憶體做法(見下表),先向用戶說明「原本那條路已因記憶體超標被放棄,改用 O」,再執行。 4. 改完仍需要 > 80 GiB 的話:**停下來問用戶**,不要硬跑、不要偷偷繞過守衛。 ## 低記憶體替代做法 | 原本(會爆) | 改成 | |---|---| | `x=$(cat big)`、`f.read()`、`readFileSync` 整份 | `cmd \| ... > out`、`while read line`、`f.read(1<<20)` | | 一次處理整個大檔/大目錄 | 先 `du -sh`;> 2 GiB 一律 `head -n` / `tail -n +` / `sed -n '1,50p'` 分頁 | | `python x.py` 載入全部資料 | generator / 逐 chunk;pandas `chunksize=`、`usecols`;`numpy.memmap`;改 `duckdb`/`sqlite` 讓引擎在記憶體外處理 | | 全部結果留在記憶體 | 分段落盤到 `/tmp/part_*`,最後 `cat part_* > final` | | 高並行/大 batch | `-j 1`、`--batch-size` 調小、`workers=1`、`--max-old-space-size`、`-n 1`、`xargs -n1 -P1` | | 對超大檔重複 grep/awk | 先 `split -l 100000 big.dat part_`,逐檔處理 | ## 執行前的習慣 - 跑任何吃記憶體的指令前先估量:`du -sh `、`wc -l `。 - 預估會超過 2 GiB 記憶體時,直接改用分批/串流版本,不要先跑再說。 - 需要 `prlimit` 硬上限時用 `prlimit --data=80G -- `(**不要用 `--as`**,bun/node 類程式會秒死)。