Spaces:
Paused
Paused
File size: 2,412 Bytes
c98a8c2 2554817 c98a8c2 2554817 c98a8c2 2554817 c98a8c2 2554817 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | # 記憶體上限規則(必遵守)
本機有一支記憶體守衛 `/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 <path>`、`wc -l <file>`。
- 預估會超過 2 GiB 記憶體時,直接改用分批/串流版本,不要先跑再說。
- 需要 `prlimit` 硬上限時用 `prlimit --data=80G -- <cmd>`(**不要用 `--as`**,bun/node 類程式會秒死)。 |