テクノロジー · 実用ガイド

Linux の「fork: Cannot allocate memory」— 再起動前に失敗境界を証明する

空き RAM は診断ではありません。fork の失敗状況を保存し、PID namespace の init、生の cgroup event、host の commit ledger を順に照合してから swap 追加や再起動を判断します。

process・workload・host の memory 境界を分ける図
オリジナルイラスト:ENOMEM を境界 signal として三つの ledger を保存します。 Watch at Ease

空き RAM は診断ではありません。fork の失敗状況を保存し、PID namespace の init、生の cgroup event、host の commit ledger を順に照合してから swap 追加や再起動を判断します。

fork の ENOMEM は kernel memory 不足だけでなく、対象 PID namespace の init 終了でも返ります。 host に空き memory があっても cgroup は memory.max に達し得ます。

1. 正確な fork 失敗と実行 context を保存する

再起動前に時刻、parent PID、service/container、command、syscall errno、最初の journal/trace、cgroup と namespace path を保存します。shell message だけでは拒否境界は分かりません。

drop_caches、global OOM trigger、無制限化、host reboot から始めないでください。失敗状態を消し、無関係な workload に影響し、成功理由を追えなくします。

2. PID namespace が子 process を作れると証明する

fork manual は対象 PID namespace の init 終了でも ENOMEM になると記録しています。失敗 parent と正常 process の namespace link を比較し、その namespace に生きた PID 1 があるか確認します。

この branch なら container/namespace lifecycle を修正し、supervised init を生存させます。swap 追加や MemoryMax 変更では dead namespace は直りません。

3. service cgroup と ancestor limit を監査する

失敗 PID を cgroup に対応付け、一回の controlled attempt 前後で memory.current、max、high、swap.current、memory.events を保存し、parent slice も確認します。

host 全体 pressure なしで max や oom が増えれば workload-local evidence です。OOM killer を呼ばない allocation failure もあるため oom_kill=0 は免責ではありません。

4. host commit と物理 pressure の証拠を比べる

MemAvailable、swap、CommitLimit、Committed_AS、pressure、kernel log を一緒に読みます。strict overcommit では空き memory が見えても commit ledger 到達で allocation が失敗します。

ENOMEM と task-count failure を分けます。RLIMIT_NPROC、threads-max、pid_max、pids.max は通常 EAGAIN を返すので、errno を保存してから limit を変えます。

5. 一つの境界だけ直して同じ起動を繰り返す

dead namespace は init supervision、cgroup boundary は leak 修正または狭い policy 調整、host pressure は証明済み consumer/容量を修正します。

同じ namespace、cgroup、commit ledger を見ながら二回以上同じ start を行います。child 起動、正しい supervisor、event delta なし、hidden OOM kill なし、通常 restart 成功を合格条件にします。

snapshot・repair・反復 start の受入れ図
オリジナルイラスト:証明済み原因を一つだけ変えて同じ start を検証します。 Watch at Ease