{ "version": "1.1", "id": "memory-pressure-reclaim-swap-oom", "title": "Host memory pressure가 storage와 OOM으로 갈라지는 경로", "question": "Host memory pressure가 생겼을 때 reclaim 이후 어떤 경로가 swap I/O와 storage contention으로 이어지고, 확보 실패는 어디서 OOM으로 이어지는가", "type": "data-flow", "direction": "LR", "audience": [ "VM host 메모리 압박을 추적하는 개발자", "swap과 OOM의 발생 계층을 구분하려는 운영자" ], "summary": "Host memory pressure는 reclaim으로 시작한다. clean file-backed page는 버렸다가 필요할 때 storage에서 다시 읽을 수 있고 anonymous page는 Host swap I/O로 이어질 수 있다. reclaim으로도 메모리를 확보하지 못하면 Host OOM 경로가 열린다.", "alt": "Host memory pressure가 reclaim에서 clean page 재읽기, anonymous page의 Host swap과 storage contention, 메모리 확보 실패에 따른 Host OOM으로 갈라지는 흐름도. QEMU가 OOM victim이 될 때 VM 전체가 중단될 수 있다는 결과는 본문에서 설명한다.", "long_description": "왼쪽에서 Host memory pressure가 reclaim으로 들어간다. reclaim 이후 clean file-backed page는 버렸다가 필요할 때 storage에서 다시 읽는 경로, anonymous page는 Host swap I/O를 통해 physical storage와 경쟁하는 경로, 필요한 메모리를 확보하지 못하면 Host OOM으로 가는 경로로 갈린다. storage contention이 application latency로 이어지는 결과와 Host OOM이 QEMU를 victim으로 고를 때 VM 전체가 중단될 수 있다는 결과는 본문에서 이어 설명한다.", "source_context": { "document": "docs/virtualization/final/document.md", "document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210", "anchor": { "kind": "heading", "value": "제2부 — 메모리 가상화", "line": 1670 } }, "composition": { "profile": "component-flow", "diagram_only": true, "reference_ids": [ "payment-event-flow" ], "rationale": "압박 하나가 reclaim 뒤 여러 자원 경로로 갈라지고 다시 storage contention과 OOM 결과로 이어지는 흐름이 핵심이다.", "focus_node": "reclaim" }, "groups": [], "nodes": [ { "id": "pressure", "label": "Host memory pressure", "kind": "resource", "role": "source", "description": "실제 Host RAM 수요가 available physical memory에 접근한 상태.", "evidence": [ { "start_line": 2818, "end_line": 2831 } ], "assumption": false }, { "id": "reclaim", "label": "Reclaim", "kind": "component", "role": "service", "emphasis": "primary", "description": "Linux가 회수 가능한 page/cache를 처리하는 첫 대응.", "evidence": [ { "start_line": 2818, "end_line": 2831 } ], "assumption": false }, { "id": "clean-page", "label": "clean file-backed page", "kind": "data", "role": "service", "details": [ "discard · reread" ], "description": "원본이 storage에 있어 RAM에서 제거하고 나중에 다시 읽을 수 있다.", "evidence": [ { "start_line": 2834, "end_line": 2848 } ], "assumption": false }, { "id": "host-swap", "label": "Host swap I/O", "kind": "storage", "role": "store", "details": [ "anonymous page" ], "description": "anonymous page의 backing이 필요할 때 host swap I/O가 생길 수 있다.", "evidence": [ { "start_line": 2850, "end_line": 2852 }, { "start_line": 2856, "end_line": 2886 } ], "assumption": false }, { "id": "storage", "label": "Storage contention", "kind": "storage", "role": "store", "shape": "database", "details": [ "Host swap", "DB I/O", "writeback" ], "description": "여러 I/O가 한 physical device에 몰려 contention을 만든다.", "evidence": [ { "start_line": 2938, "end_line": 2965 } ], "assumption": false }, { "id": "host-oom", "label": "Host OOM", "kind": "result", "role": "service", "description": "reclaim 등으로도 필요한 memory 확보에 실패했을 때 Host kernel에서 발생할 수 있다.", "evidence": [ { "start_line": 3213, "end_line": 3231 }, { "start_line": 3249, "end_line": 3265 } ], "assumption": false } ], "edges": [ { "id": "pressure-reclaim", "from": "pressure", "to": "reclaim", "label": "pressure", "kind": "control", "evidence": [ { "start_line": 2818, "end_line": 2831 } ], "assumption": false }, { "id": "reclaim-clean", "from": "reclaim", "to": "clean-page", "label": "file-backed", "kind": "control", "evidence": [ { "start_line": 2834, "end_line": 2848 } ], "assumption": false }, { "id": "clean-storage", "from": "clean-page", "to": "storage", "label": "reread", "kind": "data", "style": "dashed", "evidence": [ { "start_line": 2834, "end_line": 2848 } ], "assumption": false }, { "id": "reclaim-swap", "from": "reclaim", "to": "host-swap", "label": "anonymous", "kind": "data", "evidence": [ { "start_line": 2850, "end_line": 2852 } ], "assumption": false }, { "id": "swap-storage", "from": "host-swap", "to": "storage", "label": "swap", "kind": "data", "evidence": [ { "start_line": 2871, "end_line": 2886 }, { "start_line": 2940, "end_line": 2946 } ], "assumption": false }, { "id": "reclaim-oom", "from": "reclaim", "to": "host-oom", "label": "확보 실패", "kind": "control", "style": "dashed", "evidence": [ { "start_line": 3213, "end_line": 3231 } ], "assumption": false } ], "legend": [], "metadata": { "rationale": "분기와 재합류를 모두 넣어 자동 배치가 교차하던 이전 안을 줄였다. 그림은 Host pressure가 reclaim 뒤 clean-page·Host swap·Host OOM으로 갈리는 구조까지만 보이고, application latency와 QEMU victim 결과는 본문에 남긴다." } }