Skip to content

필사 모드: 리눅스 메모리 계층 해킹 — swap, zram, 그리고 VRAM을 스왑으로 쓰는 역발상

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.
원문 렌더가 준비되기 전까지 텍스트 가이드로 표시합니다.

들어가며 — 남는 VRAM을 스왑으로 쓴다고?

최근 Hacker News에서 nbd-vram이라는 프로젝트가 프런트페이지에 올라 한바탕 토론을 일으켰습니다. 아이디어는 단순하고 도발적입니다. 요즘 GPU에는 VRAM이 16GB, 24GB씩 달려 있는데, 게임이나 LLM 추론을 돌리지 않는 시간에는 대부분 놀고 있습니다. 그렇다면 이 빠른 메모리를 NBD(Network Block Device)로 노출해서 리눅스 스왑 디바이스로 쓰면 어떨까? SSD 스왑보다 훨씬 빠른 스왑 계층이 공짜로 생기는 셈입니다.

댓글란은 둘로 갈렸습니다. "PCIe 4.0 x16이면 이론상 초당 32GB인데 NVMe보다 5배 빠른 스왑이 맞다"는 흥분과, "그 돈으로 RAM을 더 사라"는 냉소가 공존했죠. 하지만 이 논쟁이 진짜 가치 있는 이유는 따로 있습니다. 스왑이 무엇이고, 리눅스가 메모리를 어떻게 계층화하는지, zram과 zswap은 어디에 끼어드는지를 제대로 이해해야 이 역발상의 합리성을 판단할 수 있기 때문입니다.

이 글은 nbd-vram을 훅으로 삼아, 리눅스 메모리 관리의 기초부터 스왑 튜닝, 압축 메모리(zram/zswap), OOM 대응, cgroup v2 메모리 제어, 컨테이너 환경의 함정까지 한 번에 정리합니다.

리눅스 메모리 관리 기초 — 스왑에 대한 오해부터

페이지 캐시와 익명 페이지

리눅스가 다루는 메모리 페이지는 크게 두 종류입니다.

┌──────────────────────── 물리 RAM ────────────────────────┐

│ │

│ 파일 기반 페이지 (page cache) 익명 페이지 (anonymous) │

│ ─ 실행 파일, 라이브러리 ─ 힙(malloc), 스택 │

│ ─ 읽은 파일의 캐시 ─ 공유 메모리 │

│ → 디스크에 원본이 있음 → 디스크에 원본이 없음 │

│ → 회수: 그냥 버리면 됨 → 회수: 스왑에 써야 함 │

│ (더러우면 writeback) │

└──────────────────────────────────────────────────────────┘

핵심은 이것입니다. 파일 기반 페이지는 디스크에 원본이 있으므로 메모리가 부족하면 그냥 버리면 됩니다(수정된 페이지는 파일에 다시 쓰고). 반면 익명 페이지는 원본이 없으므로, 버리려면 어딘가에 내용을 보관해야 합니다. 그 보관소가 스왑입니다.

"스왑은 느려지는 원인"이라는 오해

흔한 오해와 달리, 스왑이 없으면 시스템이 더 빨라지는 게 아닙니다. 스왑이 없으면 커널은 메모리 압박 시 익명 페이지를 회수할 방법이 없어서, 파일 기반 페이지(코드, 라이브러리!)만 계속 버리게 됩니다. 그 결과 방금 버린 실행 코드를 디스크에서 다시 읽어오는 일이 반복되는데, 이것이 악명 높은 thrashing입니다. 한 번도 안 쓰는 초기화 코드 같은 차가운 익명 페이지를 스왑으로 보내고, 그 자리에 뜨거운 페이지 캐시를 유지하는 것이 전체 성능에 유리한 경우가 많습니다.

요약하면, 스왑은 "메모리가 모자랄 때를 위한 비상구"가 아니라 "메모리 회수의 선택지를 넓혀주는 장치"입니다. 커널 개발자 Chris Down의 "In defence of swap" 글이 이 관점을 잘 설명합니다.

swappiness — 무엇과 무엇의 균형인가

vm.swappiness는 0~200 범위의 값으로(구버전 문서는 0~100), 메모리 회수 시 익명 페이지와 파일 페이지 중 어느 쪽을 더 적극적으로 회수할지의 균형을 정합니다. "스왑을 얼마나 빨리 시작할지"가 아닙니다.

현재 값 확인

cat /proc/sys/vm/swappiness

일시 변경

sudo sysctl vm.swappiness=100

영구 설정

echo 'vm.swappiness = 100' | sudo tee /etc/sysctl.d/99-swap.conf

sudo sysctl --system

값의 직관은 다음과 같습니다.

| 값 | 의미 | 적합한 환경 |

| --- | --- | --- |

| 0~10 | 익명 페이지 회수를 극도로 기피 | 스왑이 매우 느린 HDD, DB 전용 서버 |

| 60 | 기본값, 파일 페이지 회수 선호 | 일반 서버 |

| 100 | 익명과 파일을 동등하게 취급 | zram/zswap 등 빠른 스왑 |

| 100~200 | 익명 페이지 회수를 더 선호 | 매우 빠른 스왑 + 큰 페이지 캐시 수요 |

zram처럼 스왑이 RAM 속도에 가까운 환경에서는 swappiness를 100 이상으로 올리는 것이 정석입니다. 비용 모델이 바뀌었기 때문입니다.

zram vs zswap — 압축 메모리 계층 정리

둘 다 "압축으로 RAM을 늘리는" 기술이지만 아키텍처가 다릅니다. 헷갈리기 쉬우니 그림으로 비교합니다.

[zram] [zswap]

익명 페이지 회수 익명 페이지 회수

│ │

▼ ▼

zram 블록 디바이스 zswap 압축 풀 (RAM 캐시)

(= RAM 내 압축 스왑) │ 가득 차면/오래되면

│ ▼

▼ 실제 스왑 디바이스

끝. (뒤에 디스크 없음*) (SSD/HDD에 writeback)

* writeback 옵션으로 보조 디바이스 지정은 가능

| 항목 | zram | zswap |

| --- | --- | --- |

| 형태 | 압축 RAM 블록 디바이스 | 스왑 앞단의 압축 캐시 |

| 디스크 스왑 필요 | 불필요 (단독 동작) | 필수 (뒤에 실제 스왑 필요) |

| 차가운 페이지 처리 | RAM에 계속 점유 | 디스크로 밀어냄 (LRU) |

| 압축 불가 페이지 | RAM에 그대로 | 디스크로 우회 |

| 적합 환경 | 디스크 스왑 없는 장비, 노트북 | 스왑 디스크가 있는 서버 |

| 대표 사용처 | ChromeOS, Android, Fedora 기본 | 일부 서버 배포판 |

zram 실전 설정

Fedora가 기본 채택한 zram-generator 방식이 가장 깔끔합니다.

/etc/systemd/zram-generator.conf

[zram0]

RAM의 절반, 최대 8GiB

zram-size = min(ram / 2, 8192)

compression-algorithm = zstd

swap-priority = 100

수동으로 구성한다면 다음과 같습니다.

모듈 로드 후 디바이스 구성

sudo modprobe zram num_devices=1

echo zstd | sudo tee /sys/block/zram0/comp_algorithm

echo 8G | sudo tee /sys/block/zram0/disksize

sudo mkswap /dev/zram0

sudo swapon -p 100 /dev/zram0

동작 확인 — 압축률(DATA 대비 COMPR)을 주목

zramctl

NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT

/dev/zram0 zstd 8G 1.2G 310M 330M 8 [SWAP]

압축 알고리즘은 lzo-rle(빠름, 압축률 낮음)와 zstd(약간 느림, 압축률 높음)가 양대 선택지입니다. 최신 CPU라면 zstd가 대체로 우세합니다. 압축률은 워크로드에 따라 2~4배 범위가 일반적입니다.

zswap 실전 설정

zswap은 커널 빌트인이라 켜기만 하면 됩니다. 단, 뒤에 실제 스왑 디바이스가 있어야 의미가 있습니다.

부팅 시 활성화 — 커널 커맨드라인에 추가

zswap.enabled=1 zswap.compressor=zstd zswap.max_pool_percent=20

런타임 토글

echo 1 | sudo tee /sys/module/zswap/parameters/enabled

echo zstd | sudo tee /sys/module/zswap/parameters/compressor

echo 20 | sudo tee /sys/module/zswap/parameters/max_pool_percent

통계 확인 (debugfs)

sudo grep -r . /sys/kernel/debug/zswap/

선택 기준은 간단합니다. 디스크 스왑을 두고 싶지 않거나 둘 수 없는 장비(저장장치 수명이 걱정되는 노트북, 임베디드)는 zram, 이미 SSD 스왑이 있는 서버에서 스왑 IO를 줄이고 싶다면 zswap입니다. 둘을 동시에 쓰는 것은 압축을 두 번 하게 되는 안티패턴이니 피하세요.

NBD — 네트워크 블록 디바이스의 원리

nbd-vram을 이해하려면 NBD를 알아야 합니다. NBD는 "블록 디바이스 읽기/쓰기 요청을 소켓 너머의 서버에 전달하는" 단순한 프로토콜입니다.

┌─────────── 클라이언트 ───────────┐ ┌────── 서버 프로세스 ──────┐

│ 앱 → /dev/nbd0 (블록 디바이스) │ │ 요청을 받아서 │

│ │ │ │ "저장 공간"에 반영 │

│ nbd 커널 모듈 │ 소켓 │ │

│ └──── read/write ───────┼─────▶│ 저장 공간의 정체는 자유: │

│ │ │ 파일, RAM, 원격 디스크, │

│ │ │ ...또는 GPU VRAM │

└─────────────────────────────────┘ └──────────────────────────┘

서버가 요청을 어디에 저장하든 클라이언트는 알 바 아니라는 점이 핵심입니다. nbd-vram은 이 서버를 CUDA/OpenCL로 구현해, 블록 쓰기를 VRAM 버퍼에 cudaMemcpy하는 방식으로 "VRAM 디스크"를 만듭니다. 같은 호스트 안에서 유닉스 소켓으로 연결하면 네트워크 오버헤드도 최소화됩니다.

개념 흐름 (nbd-vram README 기준)

1. VRAM을 백엔드로 쓰는 nbd 서버 기동 (예: 8GB 할당)

./nbd-vram-server --size 8G --socket /run/nbd-vram.sock &

2. 클라이언트 연결 → /dev/nbd0 생성

sudo nbd-client -unix /run/nbd-vram.sock /dev/nbd0

3. 스왑으로 사용

sudo mkswap /dev/nbd0

sudo swapon -p 50 /dev/nbd0 # SSD 스왑보다 높은 우선순위

VRAM 스왑의 성능 산수 — PCIe 대역폭으로 따져보기

이 아이디어가 합리적인지는 숫자로 판단할 수 있습니다. 메모리 계층별 대략적인 대역폭과 지연을 비교해봅시다.

| 계층 | 대역폭(대략) | 지연(대략) |

| --- | --- | --- |

| DDR5 RAM | 50~80 GB/s | 80~100 ns |

| GPU VRAM (PCIe 4.0 x16 경유) | 이론 32 GB/s, 실효 20~25 GB/s | 마이크로초 단위 |

| NVMe SSD (PCIe 4.0 x4) | 5~7 GB/s | 수십 마이크로초 |

| SATA SSD | 0.55 GB/s | 수백 마이크로초 |

| zram (zstd, RAM 내) | CPU 의존, 수 GB/s | 압축/해제 비용 |

산수는 명확합니다. PCIe 4.0 x16을 거치는 VRAM 접근은 NVMe 스왑보다 대역폭 기준 3~5배 빠르고 지연은 한 자릿수 이상 낮습니다. PCIe 5.0 x16(이론 64 GB/s)이라면 격차는 더 벌어집니다. 다만 잊지 말아야 할 것은 NBD 경로의 오버헤드입니다. 페이지 폴트 → 블록 계층 → nbd 커널 모듈 → 유저스페이스 서버 → CUDA 복사라는 경로는 각 단계마다 컨텍스트 스위치와 복사를 수반하므로, 이론 대역폭을 다 뽑지는 못합니다. 그래도 NVMe보다 빠른 스왑이라는 결론 자체는 대체로 유효합니다.

합리적인 경우와 아닌 경우

합리적인 경우는 이렇습니다.

- 데스크톱에 게이밍 GPU가 있는데 평일 업무 시간에는 VRAM이 놀고 있는 경우

- RAM 증설이 물리적으로 불가능한 장비(슬롯 한계, 노트북)에서 일시적 대용량 작업

- 실험과 학습 목적 — 블록 계층, NBD, GPU 메모리를 한 번에 배우는 훌륭한 교보재

피해야 하는 경우는 더 명확합니다.

- GPU를 실제로 쓰는 워크로드(LLM 추론, 게임)와 병행 — VRAM 경합과 스왑 디바이스 소실 위험

- 프로덕션 서버 — GPU 드라이버/프로세스 장애가 곧 스왑 디바이스 장애가 되어, 스왑 안의 익명 페이지를 잃으면 커널은 해당 프로세스를 죽일 수밖에 없습니다

- 절전/서스펜드가 잦은 노트북 — 서스펜드 중 VRAM 내용 보존은 보장되지 않습니다

요컨대 "재미있고 교육적이며 특정 상황에서 실용적이지만, RAM 증설이 가능하다면 RAM을 사는 것이 정답"이라는 HN 댓글의 중론이 타당합니다.

OOM — 커널의 최후 수단과 유저스페이스 보완

커널 OOM killer의 문제

메모리가 진짜로 바닥나면 커널 OOM killer가 점수(oom_score)가 가장 높은 프로세스를 죽입니다. 문제는 발동 시점이 너무 늦다는 것입니다. 커널 OOM killer는 "마지막 페이지까지 다 써버린" 순간에야 움직이므로, 그 직전 수 분간 시스템은 thrashing으로 사실상 멈춰 있는 경우가 많습니다.

프로세스별 OOM 점수 확인

cat /proc/1234/oom_score

중요한 프로세스를 OOM 대상에서 보호 (-1000이면 면제)

echo -500 | sudo tee /proc/1234/oom_score_adj

earlyoom과 systemd-oomd

그래서 "더 일찍, 더 똑똑하게" 개입하는 유저스페이스 데몬이 등장했습니다.

earlyoom — 가용 메모리/스왑이 임계치 밑으로 가면 선제 kill

sudo apt install earlyoom

메모리 10%, 스왑 5% 미만 시 발동, 특정 프로세스 우선 종료

sudo tee /etc/default/earlyoom <<'EOF'

EARLYOOM_ARGS="-m 10 -s 5 --avoid '(^|/)(sshd|systemd)$' --prefer '(^|/)(chrome|java)$'"

EOF

sudo systemctl enable --now earlyoom

systemd-oomd는 한 걸음 더 나아가 PSI(Pressure Stall Information)를 봅니다. "메모리가 몇 % 남았나"가 아니라 "메모리 때문에 프로세스가 얼마나 오래 기다리고 있나"를 기준으로, cgroup 단위로 통째로 종료합니다.

PSI 직접 보기 — some: 일부 태스크가 대기, full: 전부 대기

cat /proc/pressure/memory

some avg10=0.00 avg60=0.12 avg300=0.05 total=8123456

full avg10=0.00 avg60=0.03 avg300=0.01 total=2345678

systemd-oomd 상태

oomctl

systemctl status systemd-oomd

데스크톱이라면 earlyoom이나 systemd-oomd 중 하나는 켜두는 것을 강력히 권합니다. "브라우저 탭 하나가 시스템 전체를 인질로 잡는" 사태를 막아줍니다.

cgroup v2 — 프로세스 그룹 단위 메모리 제어

시스템 전역 튜닝보다 더 정밀한 도구가 cgroup v2의 메모리 컨트롤러입니다. 핵심 노브는 네 가지입니다.

| 노브 | 의미 | 초과 시 동작 |

| --- | --- | --- |

| memory.min | 절대 보장 (회수 면제) | 다른 cgroup이 양보 |

| memory.low | 소프트 보호 | 여유 있을 때만 보호 |

| memory.high | 소프트 상한 | 스로틀 + 적극 회수 (kill 없음) |

| memory.max | 하드 상한 | 초과 시 OOM kill |

memory.high가 특히 유용합니다. 한도에 닿으면 프로세스를 죽이는 대신 할당 속도를 늦추고 회수를 강제하므로, "배치 작업이 메모리를 너무 먹지만 죽이고 싶지는 않은" 상황에 딱 맞습니다.

systemd 서비스에 적용하는 것이 가장 깔끔

sudo systemctl set-property batch-job.service MemoryHigh=4G MemoryMax=6G

일회성 명령을 제한된 cgroup에서 실행

systemd-run --scope -p MemoryHigh=2G -p MemoryMax=3G ./heavy-script.sh

cgroup별 메모리 사용 현황

systemd-cgtop -m

cat /sys/fs/cgroup/system.slice/batch-job.service/memory.current

스왑도 cgroup 단위로 제어할 수 있습니다. memory.swap.max를 0으로 두면 해당 그룹만 스왑을 금지할 수 있어, "DB는 스왑 금지, 배치는 스왑 허용" 같은 정책이 가능합니다.

컨테이너 환경의 메모리 함정

컨테이너에서는 위 개념들이 미묘하게 비틀립니다. 자주 당하는 함정 세 가지입니다.

**함정 1 — 컨테이너 안의 free는 호스트 수치를 보여준다.** 컨테이너 안에서 free -h를 치면 cgroup 한도가 아니라 호스트 전체 메모리가 보입니다. 애플리케이션이 "메모리가 충분하다"고 오판해 캐시를 키우다가 OOM kill 당하는 고전적 패턴입니다. JVM이나 .NET처럼 컨테이너 인지(container-aware) 런타임은 cgroup 한도를 읽지만, 직접 free를 파싱하는 스크립트는 전부 틀립니다.

컨테이너 안에서 진짜 한도를 보는 법

cat /sys/fs/cgroup/memory.max # 하드 한도

cat /sys/fs/cgroup/memory.current # 현재 사용량

**함정 2 — 페이지 캐시도 컨테이너 메모리에 포함된다.** 컨테이너가 파일을 많이 읽으면 페이지 캐시가 memory.current에 잡힙니다. "내 앱은 1GB만 쓰는데 왜 한도에 닿지?"의 정체가 대개 이것입니다. 캐시는 압박 시 회수되므로 보통은 무해하지만, memory.max 기반 OOM 판정 직전의 movable 캐시 양을 모르면 모니터링 그래프를 오독하게 됩니다. working set 지표(쿠버네티스의 container_memory_working_set_bytes)를 보세요.

**함정 3 — 쿠버네티스는 스왑을 (오랫동안) 꺼왔다.** 쿠버네티스는 노드 스왑을 기본 비활성화해왔고, 1.28 이후에야 NodeSwap 기능이 베타로 들어왔습니다. 호스트에서 zram을 켰는데 kubelet이 스왑 감지로 기동을 거부하는 사례, requests/limits 산정이 스왑을 고려하지 않아 생기는 혼선 등이 여전히 현장에 남아 있습니다. 컨테이너 노드에서 압축 메모리를 쓰려면 zswap이 아니라 (스왑처럼 보이지 않는) 다른 접근이 필요한지, kubelet 설정(failSwapOn=false, swapBehavior)을 함께 검토해야 합니다.

관측 — /proc/meminfo와 smem 읽는 법

튜닝의 전제는 측정입니다. 최소한 이 지표들은 읽을 수 있어야 합니다.

$ grep -E 'MemTotal|MemAvailable|Buffers|^Cached|SwapTotal|SwapFree|Dirty|AnonPages' /proc/meminfo

MemTotal: 32768000 kB

MemAvailable: 18234560 kB # ← free가 아니라 이걸 봐야 함

Buffers: 512000 kB

Cached: 9876000 kB # 페이지 캐시

SwapTotal: 8388604 kB

SwapFree: 7340032 kB

Dirty: 12340 kB # writeback 대기 중인 더러운 페이지

AnonPages: 10240000 kB # 익명 페이지 총량

MemFree가 작다고 메모리 부족이 아닙니다. 페이지 캐시는 언제든 회수 가능하므로, "지금 새 워크로드에 내줄 수 있는 양"인 MemAvailable이 실질 지표입니다.

프로세스별 메모리는 RSS의 함정(공유 라이브러리 중복 계산)을 피해 PSS를 봐야 정확합니다.

smem — PSS(비례 배분된 실제 점유) 기준 상위 프로세스

sudo smem -rs pss | head

PID User Command Swap USS PSS RSS

2143 app java -Xmx4g ... 0 3145728 3167234 3210240

1021 app postgres: writer 0 102400 145000 512000

스왑을 누가 쓰는지 프로세스별로 확인

sudo smem -rs swap | head

시스템 전체 스왑 인/아웃 추세 (si/so 열)

vmstat 1 5

vmstat의 si/so가 지속적으로 0이 아니면 스왑 thrashing을 의심하고, PSI(/proc/pressure/memory)로 실제 지연 영향을 확인하는 순서가 정석입니다.

실험 벤치마크 방법론 — VRAM 스왑을 검증한다면

nbd-vram 같은 실험적 구성을 평가할 때의 방법론을 정리합니다. 핵심은 "스왑 성능은 처리량이 아니라 지연 분포로 측정한다"입니다.

1. 베이스라인: 디바이스 자체 성능 (fio, 4K 랜덤 — 스왑 IO 패턴 모사)

sudo fio --name=swaptest --filename=/dev/nbd0 --rw=randrw --bs=4k \

--iodepth=32 --runtime=60 --time_based --direct=1 --group_reporting

2. 실제 스왑 부하: RAM보다 큰 working set을 강제로 만들기

stress-ng --vm 4 --vm-bytes 120% --vm-method flip --metrics-brief -t 120

3. 관측: 부하 중 스왑 인/아웃과 PSI를 함께 기록

vmstat 1 > vmstat.log &

while true; do cat /proc/pressure/memory >> psi.log; sleep 1; done &

4. 체감 지표: 부하 중 무관한 작업의 지연 측정 (예: 셸 응답)

time ls -R /usr/share > /dev/null

비교군은 최소 세 가지를 두세요. NVMe 스왑 단독, zram 단독, 그리고 실험 구성(VRAM 스왑)입니다. 각 구성에서 동일한 stress-ng 시나리오를 돌리고, 평균이 아니라 p99 지연과 PSI full 시간을 비교해야 실사용 체감과 일치하는 결론이 나옵니다. 또 하나, 재부팅 간 캐시 상태를 통일하기 위해 측정 전 페이지 캐시를 비우는 것을 잊지 마세요.

측정 전 캐시 드롭 (벤치마크 외에는 쓰지 말 것)

sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

부록 — 디스크 스왑 빠른 레시피

zram/zswap 이전의 기본기인 스왑 파일 생성도 정리해둡니다. 파티션 재구성 없이 즉시 추가할 수 있어 응급 대응에 특히 유용합니다.

4GB 스왑 파일 생성 (ext4/xfs)

sudo fallocate -l 4G /swapfile

sudo chmod 600 /swapfile

sudo mkswap /swapfile

sudo swapon /swapfile

부팅 시 자동 활성화

echo '/swapfile none swap defaults 0 0' | sudo tee -a /etc/fstab

btrfs는 전용 명령으로 (CoW/압축 속성 처리를 알아서 해줌)

sudo btrfs filesystem mkswapfile --size 4g /swap/swapfile

우선순위 확인 — 숫자가 클수록 먼저 사용됨

swapon --show

cat /proc/swaps

여러 스왑 디바이스가 있을 때 커널은 우선순위가 높은 쪽부터 사용합니다. zram을 100, 디스크 스왑을 10처럼 두면 "빠른 계층 먼저, 넘치면 디스크"라는 자연스러운 폭포 구조가 만들어집니다.

실무 권장 구성 요약

환경별로 정리하면 다음과 같습니다.

| 환경 | 권장 구성 |

| --- | --- |

| 데스크톱/노트북 (16GB 이하) | zram (RAM의 절반, zstd) + swappiness 100~180 + earlyoom |

| 데스크톱 (32GB 이상) | zram 4~8GB + systemd-oomd, 디스크 스왑은 소량 |

| 일반 서버 (SSD 있음) | zswap + NVMe 스왑 파티션 + memory.high로 서비스별 상한 |

| DB 서버 | 스왑 소량 유지 + 해당 cgroup만 memory.swap.max=0 + swappiness 낮게 |

| 쿠버네티스 노드 | 기본은 스왑 없이 requests/limits 정밀화, NodeSwap은 신중히 |

| GPU 놀고 있는 워크스테이션 | (재미로) nbd-vram 스왑 + 우선순위는 zram보다 낮게 |

마치며

nbd-vram은 어찌 보면 장난감입니다. 하지만 좋은 장난감이 늘 그렇듯, 갖고 놀다 보면 진지한 지식이 따라옵니다. 스왑은 악이 아니라 메모리 회수의 선택지라는 것, 압축 메모리(zram/zswap)는 이미 주류 배포판의 기본값이 됐다는 것, OOM은 커널에만 맡기지 말고 PSI 기반으로 선제 대응해야 한다는 것, 그리고 컨테이너 시대의 메모리 관측은 cgroup 파일을 직접 읽는 데서 시작한다는 것까지.

2026년의 우리는 AI 워크로드 덕분에 어느 때보다 메모리 계층에 민감해졌습니다. VRAM과 RAM의 경계가 흐려지는 시대(통합 메모리 아키텍처의 확산)에, 블록 디바이스 추상화 하나로 GPU 메모리를 스왑으로 둔갑시키는 이 프로젝트는 리눅스 추상화 설계의 우아함을 보여주는 좋은 사례이기도 합니다. 주말에 한 번 직접 굴려보시기를 권합니다. 단, 프로덕션은 말고요.

참고 자료

- nbd-vram (GitHub): https://github.com/c0dejedi/nbd-vram

- Hacker News 토론: https://news.ycombinator.com/

- 커널 공식 문서 — zram: https://docs.kernel.org/admin-guide/blockdev/zram.html

- 커널 공식 문서 — zswap: https://docs.kernel.org/admin-guide/mm/zswap.html

- 커널 공식 문서 — cgroup v2: https://docs.kernel.org/admin-guide/cgroup-v2.html

- 커널 공식 문서 — sysctl/vm (swappiness 등): https://docs.kernel.org/admin-guide/sysctl/vm.html

- Chris Down — In defence of swap: https://chrisdown.name/2018/01/02/in-defence-of-swap.html

- PSI (Pressure Stall Information) 문서: https://docs.kernel.org/accounting/psi.html

- earlyoom (GitHub): https://github.com/rfjakob/earlyoom

- systemd-oomd 매뉴얼: https://www.freedesktop.org/software/systemd/man/latest/systemd-oomd.service.html

- 쿠버네티스 — 스왑 메모리 관리 블로그: https://kubernetes.io/blog/2023/08/24/swap-linux-beta/

- GeekNews: https://news.hada.io/

현재 단락 (1/197)

최근 Hacker News에서 nbd-vram이라는 프로젝트가 프런트페이지에 올라 한바탕 토론을 일으켰습니다. 아이디어는 단순하고 도발적입니다. 요즘 GPU에는 VRAM이 16GB...

작성 글자: 0원문 글자: 10,873작성 단락: 0/197