우분투 24.04 스왑 파일 추가·크기 변경: swapon, fstab, swappiness 설정과 메모리 부족 대처

이 글의 핵심

free -h에서 Swap이 0이거나 빌드 중에 프로세스가 Killed로 죽는다면 스왑 파일을 추가할 차례일 수 있습니다. 이 글은 우분투 24.04에서 현재 스왑 확인 → 스왑 파일 생성(fallocate와 dd) → fstab 등록과 검증 → 크기 변경 → swappiness 조정 순서로 설명하고, 각 단계에서 실제로 출력되는 오류 메시지와 해결법, 스왑이 도움이 되는 경우와 오히려 느려지는 경우를 함께 다룹니다.

스왑이 필요해지는 순간

스왑을 찾아보게 되는 계기는 대개 비슷합니다. RAM 1~2GB짜리 클라우드 VM에서 npm run build나 cargo build를 돌렸더니 SSH 세션이 멈추고, 한참 뒤에 터미널에 Killed 한 단어만 남습니다. 또는 데스크톱에서 브라우저 탭과 IDE를 잔뜩 띄웠더니 갑자기 창이 닫혀 버립니다. 이럴 때 free -h를 쳐 보면 Swap 줄이 0B로 비어 있거나, 기본으로 잡힌 스왑이 이미 꽉 차 있습니다.

스왑은 RAM이 모자랄 때 당장 쓰지 않는 메모리 페이지를 디스크로 내보내는 공간입니다. RAM을 늘려 주지는 않지만, 메모리 사용량이 잠깐 튀는 순간에 커널이 프로세스를 강제로 죽이는 대신 느리게라도 버틸 여지를 줍니다. 이 글은 그 스왑을 파일 형태로 추가하고, 크기를 바꾸고, 동작 방식을 조정하는 방법을 다룹니다.

기준 환경: 우분투 24.04 LTS(데스크톱 설치와 클라우드 서버 이미지), 기본 ext4 루트 파일 시스템. btrfs를 쓰는 경우는 별도 절에서 다룹니다. 명령은 모두 sudo 권한이 있는 일반 사용자 기준입니다.

메모리가 어떻게 페이지 단위로 관리되고 페이지 캐시가 무엇인지부터 알고 싶다면 리눅스 메모리 관리 글을 먼저 보면 아래의 swappiness 설명이 훨씬 잘 읽힙니다.

지금 스왑이 있는지 확인하기

먼저 현재 상태를 봅니다. 두 명령이면 충분합니다.

swapon --show
free -h

데스크톱 설치 직후라면 보통 이런 결과가 나옵니다.

NAME      TYPE SIZE USED PRIO
/swap.img file   4G   0B   -2

               total        used        free      shared  buff/cache   available
Mem:            15Gi       3.1Gi       9.2Gi       412Mi       3.4Gi        12Gi
Swap:          4.0Gi          0B       4.0Gi

swapon --show가 아무것도 출력하지 않고 free -h의 Swap 줄이 전부 0B라면 스왑이 하나도 없는 상태입니다.

데스크톱과 클라우드 이미지의 기본값이 다르다

우분투 데스크톱 설치 프로그램은 별도 스왑 파티션 대신 루트 파일 시스템에 /swap.img라는 스왑 파일을 만들고 /etc/fstab에 등록합니다. 크기는 설치 시점의 RAM과 디스크 크기에 따라 자동으로 정해지므로 기기마다 다릅니다. 반면 AWS, GCP, Azure 등에서 제공하는 우분투 클라우드 이미지는 대부분 스왑 없이 부팅됩니다. 클라우드 쪽은 디스크가 네트워크 스토리지인 경우가 많고, 인스턴스 크기를 고르는 것으로 메모리를 맞추라는 전제가 깔려 있기 때문입니다. 그래서 “로컬에서는 잘 되던 빌드가 같은 우분투 24.04 VM에서는 죽는다”는 일이 자주 생깁니다.

/etc/fstab을 열어 스왑 줄을 확인해 두면 나중에 수정할 때 헷갈리지 않습니다.

grep -i swap /etc/fstab
/swap.img	none	swap	sw	0	0

스왑 파일 만들기: fallocate, chmod, mkswap, swapon

여기서는 스왑이 없는 VM에 2GB 스왑 파일 /swapfile을 만든다고 가정합니다. 크기는 아래 “크기를 정하는 기준”에서 다시 이야기하고, 먼저 디스크 여유 공간부터 확인합니다. 스왑 파일은 만드는 즉시 그 크기만큼 디스크를 실제로 차지하므로, 여유가 빠듯한 루트 파티션에 만들면 이번에는 디스크가 가득 차는 문제가 생깁니다.

df -h /

디스크가 이미 꽉 차 있다면 디스크·inode 가득 참 해결 글을 참고해 공간부터 확보하는 것이 순서입니다.

1단계: 공간 할당

sudo fallocate -l 2G /swapfile

fallocate는 파일 시스템에 “이 파일에 블록 2GB를 미리 잡아 달라”고 요청하는 명령이라 거의 즉시 끝납니다. ext4에서는 이렇게 할당한 파일을 스왑으로 그대로 쓸 수 있습니다.

fallocate가 실패하거나, 뒤에서 볼 swapon이 파일을 거부하면 dd로 실제 0을 채워 넣습니다. 2GB를 실제로 쓰기 때문에 디스크 속도에 따라 수십 초 이상 걸릴 수 있습니다.

sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress

1-1: “it appears to have holes” 오류와 dd가 필요한 경우

스왑 파일에는 구멍(hole)이 있으면 안 됩니다. 구멍이란 파일 크기상으로는 존재하지만 실제 디스크 블록이 배정되지 않은 구간입니다. 커널은 스왑을 켤 때 파일의 블록 위치를 미리 계산해 두고 이후 파일 시스템을 거치지 않고 그 블록에 직접 읽고 씁니다. 블록이 배정되지 않은 구간이 있으면 이 방식이 성립하지 않습니다.

truncate -s 2G /swapfile이나 dd ... seek= 처럼 크기만 늘린 희소 파일(sparse file)로 스왑을 켜려 하면 이런 메시지가 나옵니다.

swapon: /swapfile: skipping - it appears to have holes.

이 경우 파일을 지우고 fallocate 또는 위의 dd if=/dev/zero 방식으로 다시 만들면 해결됩니다. 또 파일 시스템에 따라 fallocate로 할당한 미기록(unwritten) 블록을 스왑으로 받아 주지 않는 경우가 있는데, 이때는 swapon failed: Invalid argument가 나옵니다. 역시 dd로 다시 만드는 것이 가장 확실한 우회 방법입니다.

2단계: 권한을 600으로

sudo chmod 600 /swapfile

스왑 파일에는 RAM에서 밀려난 내용, 즉 비밀번호나 세션 토큰, 개인 키가 담긴 메모리 페이지가 그대로 기록될 수 있습니다. 다른 사용자가 이 파일을 읽을 수 있으면 메모리 내용을 엿볼 수 있게 되므로 root만 읽고 쓸 수 있어야 합니다. 이 단계를 빼먹으면 스왑은 켜지지만 매번 다음 경고가 나옵니다.

swapon: /swapfile: insecure permissions 0644, 0600 suggested.

일반 사용자 소유로 만들었다면 소유자 경고도 함께 나옵니다. 이때는 sudo chown root:root /swapfile까지 해 줍니다.

swapon: /swapfile: insecure file owner 1000, 0 (root) suggested.

3단계: 스왑 영역으로 포맷

sudo mkswap /swapfile
Setting up swapspace version 1, size = 2 GiB (2147479552 bytes)
no label, UUID=3c1f6a0e-....

mkswap은 파일 앞부분에 스왑 헤더(버전, 크기, UUID)를 기록합니다. 이 과정 없이 swapon을 실행하면 swapon: /swapfile: read swap header failed가 나옵니다.

4단계: 켜고 확인

sudo swapon /swapfile
swapon --show
NAME      TYPE SIZE USED PRIO
/swapfile file   2G   0B   -2

여기까지는 지금 부팅에만 적용됩니다. 재부팅하면 스왑이 다시 꺼지므로 다음 단계가 필요합니다.

재부팅 후에도 유지: /etc/fstab 등록과 검증

sudo cp /etc/fstab /etc/fstab.bak
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

필드는 순서대로 장치(파일 경로), 마운트 지점(스왑은 마운트하지 않으므로 none), 종류 swap, 옵션 sw, 덤프와 fsck 순서(0 0)입니다. 부팅 시 systemd가 이 줄을 읽어 swapfile.swap 유닛을 만들고 스왑을 켭니다.

/etc/fstab은 반드시 백업하고 수정하십시오. 이 파일에 문법 오류나 존재하지 않는 장치가 들어가면 다음 부팅 때 응급 모드(emergency mode)로 떨어질 수 있고, 클라우드 VM에서는 SSH 접속조차 안 돼 콘솔이나 복구 디스크로 들어가야 합니다.

그래서 재부팅 전에 두 가지로 검증합니다.

sudo findmnt --verify

findmnt --verify는 fstab의 각 줄을 파싱해 존재하지 않는 경로, 알 수 없는 파일 시스템 종류, 형식 오류를 경고로 알려 줍니다. 오타가 있는 줄을 재부팅 전에 잡아내는 용도입니다.

다음으로 fstab 기준으로 실제로 켜지는지 확인합니다. 이미 켜 둔 상태에서는 swapon -a가 아무 일도 하지 않으므로, 한 번 끄고 fstab만으로 다시 켭니다.

sudo swapoff /swapfile
sudo swapon -a
swapon --show

swapon -a는 fstab에 있는 스왑 항목을 모두 켜는 명령입니다. 여기서 /swapfile이 다시 목록에 보이면 재부팅 후에도 같은 결과가 나옵니다. 오류가 나면 fstab 줄의 경로를 다시 확인합니다.

btrfs 루트라면 방법이 다르다

우분투 기본 설치는 ext4지만, 직접 btrfs로 설치했다면 위 방법이 그대로는 통하지 않습니다. btrfs의 스왑 파일은 압축과 copy-on-write가 꺼져 있어야 하고 스냅숏 대상 서브볼륨에 있으면 안 되는 등 조건이 붙습니다. 우분투 24.04의 btrfs-progs에는 이 조건을 알아서 맞춰 주는 전용 명령이 있으므로 그것을 쓰는 편이 안전합니다.

sudo btrfs subvolume create /swap
sudo btrfs filesystem mkswapfile --size 2g /swap/swapfile
sudo swapon /swap/swapfile

스왑 파일을 별도 서브볼륨에 두는 이유는, 루트 서브볼륨을 스냅숏(Timeshift나 snapper 등)으로 찍을 때 스왑 파일이 걸리면 스냅숏이 실패하거나 스왑 파일이 거부되기 때문입니다. fstab 등록은 경로만 바꿔 위와 동일하게 합니다.

크기를 바꾸는 방법과 Cannot allocate memory

스왑 파일은 사용 중인 상태에서 크기를 바꿀 수 없습니다. 끄고, 다시 만들고, 켜는 순서를 밟습니다. 데스크톱의 /swap.img를 8GB로 늘리는 예입니다.

sudo swapoff /swap.img
sudo rm /swap.img
sudo fallocate -l 8G /swap.img
sudo chmod 600 /swap.img
sudo mkswap /swap.img
sudo swapon /swap.img

파일 이름을 그대로 쓰면 fstab은 손댈 필요가 없습니다. 파일 이름을 바꿨다면 fstab 줄도 같이 고칩니다. 새로 mkswap하면 UUID가 바뀌지만, fstab에 경로로 적어 두었다면 영향이 없습니다.

swapoff가 실패할 때

swapoff는 스왑에 나가 있던 페이지를 전부 RAM으로 다시 읽어 들인 뒤에야 끝납니다. 스왑 사용량이 남은 RAM보다 많으면 되돌아갈 자리가 없어 다음 오류가 납니다.

swapoff: /swap.img: swapoff failed: Cannot allocate memory

이때 선택지는 세 가지입니다.

  • 메모리를 많이 쓰는 프로그램(브라우저, IDE, 빌드)을 닫아 free -h의 available이 스왑 사용량보다 충분히 커진 뒤 다시 시도합니다.
  • 기존 파일을 끄지 않고 새 스왑 파일을 하나 더 만들어 먼저 켭니다. 그러면 기존 스왑의 페이지가 새 스왑으로 옮겨 갈 수 있어 swapoff가 성공합니다. 정리가 끝나면 원하는 구성으로 맞춥니다.
  • 급하지 않다면 fstab만 고쳐 두고 재부팅합니다.

swapoff가 오래 걸리는 것은 정상입니다. 스왑에 수 GB가 나가 있으면 그것을 전부 디스크에서 읽어 와야 하므로 몇 분이 걸리기도 하고, 그동안 시스템이 굼뜰 수 있습니다. 여러 사람이 쓰는 서버에서는 한가한 시간에 하는 것이 좋습니다.

크기를 정하는 기준

“RAM의 두 배” 같은 공식은 RAM이 수백 MB이던 시절의 관습이라 지금은 그대로 따를 이유가 없습니다. 정답이 되는 숫자는 없고, 용도에 따라 이렇게 생각하면 판단이 쉽습니다.

  • 작은 클라우드 VM(1~2GB RAM): 빌드나 패키지 설치처럼 짧게 튀는 사용량을 흡수하는 것이 목적이므로 RAM과 비슷한 크기에서 시작해 보고, 실제 사용량(swapon --show의 USED)을 보며 조정하는 방식이 무난합니다. 디스크 요금과 여유 공간도 함께 고려합니다.
  • 데스크톱(8GB 이상): 설치 프로그램이 만든 기본 크기로 대부분 충분합니다. 메모리를 많이 쓰는 작업을 하는데 스왑이 자주 꽉 찬다면 그때 늘립니다.
  • 최대 절전(하이버네이션)을 쓰려면: RAM 내용 전체를 스왑에 써야 하므로 RAM 크기 이상이 필요합니다. 아래에서 따로 설명합니다.

스왑이 클수록 좋은 것은 아닙니다. 메모리 누수가 있는 프로그램이 있으면 스왑이 큰 만큼 오래 버티다가, 그 사이 시스템 전체가 디스크 입출력에 묶여 반응이 없어지는 시간만 길어집니다.

swappiness는 “몇 % 쓰면 스왑” 이 아니다

vm.swappiness는 흔히 “RAM 사용률이 (100 - swappiness)%를 넘으면 스왑을 쓰기 시작한다”는 식으로 설명되지만 이는 틀린 설명입니다. 실제 의미는 메모리를 회수해야 할 때 커널이 어느 쪽을 먼저 비울지에 대한 상대적 가중치입니다.

메모리가 모자라면 커널이 비울 수 있는 것은 크게 두 가지입니다.

  • 파일 페이지(페이지 캐시): 디스크에 있는 파일을 읽어 둔 것. 버리면 나중에 파일에서 다시 읽으면 되므로 스왑이 필요 없습니다.
  • 익명 페이지: 프로그램이 malloc 등으로 잡은 힙·스택처럼 파일에 대응되지 않는 메모리. 비우려면 스왑에 써야 합니다.

swappiness는 이 두 종류를 회수하는 비용을 어떻게 비교할지 정합니다. 값이 낮을수록 페이지 캐시를 먼저 버리고 익명 페이지는 되도록 RAM에 남기며, 높을수록 익명 페이지도 적극적으로 스왑으로 내보내 캐시를 지킵니다. 우분투 기본값은 60이고, 최근 커널에서는 0~200 범위를 받습니다. 0으로 해도 스왑이 완전히 꺼지는 것은 아니며, 메모리가 정말 부족해지면 여전히 스왑을 씁니다.

현재 값 확인과 즉시 변경은 이렇게 합니다.

cat /proc/sys/vm/swappiness
sudo sysctl vm.swappiness=10

sysctl로 바꾼 값은 재부팅하면 사라집니다. 유지하려면 /etc/sysctl.d/에 파일을 만듭니다. /etc/sysctl.conf를 직접 고쳐도 동작하지만, 별도 파일로 두면 무엇을 바꿨는지 찾기 쉽고 패키지 업데이트와 충돌할 일도 없습니다.

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

데스크톱에서 창 전환 후 앱이 늦게 반응하는 것이 싫다면 낮은 값(10 전후)을, 대부분의 메모리를 거의 안 쓰는 상주 프로세스가 차지하는 서버라면 기본값을 유지하는 식으로 선택합니다. 값을 바꾼 효과는 워크로드마다 다르므로, 바꾼 뒤 실제 사용감이나 지표를 보고 판단하는 것이 좋습니다.

스왑과 OOM killer: Killed의 정체

RAM과 스왑이 모두 바닥나면 커널의 OOM(Out Of Memory) killer가 메모리를 가장 많이 쓰는 축에 드는 프로세스를 골라 강제 종료합니다. 터미널에는 Killed만 남기 때문에 원인을 알기 어려운데, 커널 로그를 보면 확인할 수 있습니다.

sudo dmesg -T | grep -i -E 'out of memory|killed process'
Out of memory: Killed process 23817 (node) total-vm:4523104kB, anon-rss:1702448kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:5160kB oom_score_adj:0

C++ 빌드에서는 컴파일러 프로세스가 죽어 이런 메시지로 나타납니다.

c++: fatal error: Killed signal terminated program cc1plus
compilation terminated.

우분투 데스크톱에는 커널 OOM killer와 별개로 systemd-oomd도 동작합니다. 메모리 압박이 일정 시간 이상 계속되면 커널보다 먼저 cgroup 단위로 프로세스를 정리하므로, dmesg에 아무것도 없는데 앱이 닫혔다면 이쪽 로그를 확인합니다.

journalctl -u systemd-oomd --since today

작은 VM에서 스왑이 빌드를 살리는 이유

npm install, cargo build, 큰 C++ 프로젝트 빌드는 대부분의 시간에는 메모리를 적당히 쓰다가 링크 단계나 특정 파일 컴파일에서 순간적으로 사용량이 크게 튑니다. 1~2GB VM에서 스왑이 없으면 이 순간을 넘기지 못하고 OOM으로 죽습니다. 스왑이 있으면 그 순간 덜 쓰는 페이지(쉬고 있는 데몬, 이미 끝난 단계의 데이터)를 디스크로 밀어내고 빌드를 끝까지 진행할 수 있습니다. 느려지긴 해도 실패하지는 않는 것이 핵심입니다.

다만 스왑으로 해결되지 않는 메모리 오류도 있습니다. Node.js의 다음 오류는 시스템 메모리가 아니라 V8 힙 상한에 걸린 것이라 스왑을 늘려도 사라지지 않습니다.

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory

이 경우는 NODE_OPTIONS=--max-old-space-size=2048처럼 힙 상한을 올려야 하고, 그 상한을 실제로 감당할 메모리(RAM + 스왑)가 있어야 합니다.

병렬 빌드도 함께 줄이는 것이 효과적입니다. 컴파일 작업 하나가 수백 MB를 쓰는데 make -j$(nproc)로 여러 개를 동시에 돌리면 스왑이 있어도 버거워집니다. make -j1, cargo build -j 1처럼 동시 작업 수를 줄이면 시간은 더 걸려도 최대 메모리 사용량이 크게 낮아집니다.

스왑이 오히려 느려지는 경우

스왑은 “가끔 튀는 사용량”을 흡수하는 장치이지, 상시 부족한 RAM을 대신하는 장치가 아닙니다. 지금 실행 중인 작업이 필요로 하는 메모리(working set) 자체가 RAM보다 크면, 커널은 페이지를 내보냈다가 곧바로 다시 읽어 오기를 반복합니다. 이 상태를 스래싱(thrashing)이라고 하며 CPU는 놀고 있는데 시스템 전체가 디스크를 기다리느라 SSH 입력조차 몇 초씩 밀립니다.

지금 스왑이 계속 오가고 있는지는 vmstat으로 확인합니다.

vmstat 1

si(swap in)와 so(swap out) 열이 몇 초 동안 계속 0이 아닌 큰 값으로 나온다면 스왑이 부족분을 메우고 있는 것이 아니라 시스템을 끌어내리고 있는 것입니다. 이때는 스왑을 더 키우기보다 동시 작업을 줄이거나, 메모리를 많이 쓰는 프로세스를 찾아 정리하거나(ps aux --sort=-rss | head), 인스턴스 크기를 올리는 쪽이 답입니다. 클라우드 VM의 디스크가 네트워크 블록 스토리지라면 스왑 입출력이 디스크 IOPS 한도를 같이 소모한다는 점도 염두에 두어야 합니다.

최대 절전(hibernation)과 스왑

최대 절전은 RAM 내용 전체를 스왑에 기록한 뒤 전원을 끄고, 다음 부팅 때 스왑에서 그대로 복원하는 기능입니다. 그래서 스왑이 RAM 크기 이상이어야 합니다. 우분투는 최대 절전을 기본으로 꺼 두고 전원 메뉴에도 표시하지 않습니다. 하드웨어마다 복원이 안정적이지 않은 경우가 있기 때문입니다.

스왑 파일로 최대 절전을 쓰려면 스왑 크기 외에도 커널 부팅 옵션에 resume=(스왑 파일이 있는 파티션)과 resume_offset=(파일 내 물리 오프셋)을 지정해야 하고, 보안 부팅(Secure Boot)이 켜진 상태에서는 커널 잠금(lockdown) 정책 때문에 최대 절전이 막힐 수 있습니다. 단순히 스왑을 크게 만든다고 쓸 수 있게 되는 기능은 아니므로, 필요하다면 하드웨어별 사례를 확인하고 진행하는 것이 좋습니다. 대부분의 노트북 사용자에게는 기본 절전(suspend)으로 충분합니다.

디스크 대신 압축 메모리: zram

zram은 RAM 일부를 압축된 블록 장치로 만들어 스왑으로 쓰는 방식입니다. 디스크에 쓰지 않고 메모리 안에서 압축만 하므로 디스크 스왑보다 훨씬 빠르고, 메모리 페이지는 대체로 압축이 잘 되는 편이라 실질 메모리를 늘리는 효과가 있습니다. 대신 압축에 CPU를 쓰고, 최대 절전에는 쓸 수 없습니다.

우분투 24.04에서는 두 패키지 중 하나로 설정할 수 있습니다.

# 방법 1: zram-tools (설정 파일 /etc/default/zramswap)
sudo apt install zram-tools

# 방법 2: systemd-zram-generator (설정 파일 /etc/systemd/zram-generator.conf)
sudo apt install systemd-zram-generator

둘 중 하나만 쓰십시오. zram을 디스크 스왑 파일과 함께 쓰면 zram 쪽이 더 높은 우선순위(swapon --show의 PRIO)를 받아 먼저 쓰이고, zram이 가득 찼을 때만 디스크 스왑으로 넘어갑니다. RAM이 1GB인 VM처럼 아주 작은 환경에서는 압축할 RAM 자체가 적어 효과가 제한적이므로 디스크 스왑 파일을 기본으로 두는 편이 무난합니다.

SSD에 스왑을 두면 수명이 줄어들까

스왑이 SSD 쓰기 수명을 갉아먹는다는 걱정을 자주 보지만, 일반적인 데스크톱·개발용 사용에서 스왑 때문에 SSD가 먼저 망가지는 일은 현실적인 걱정거리가 아니라는 것이 대체적인 견해입니다. 요즘 SSD의 쓰기 내구성은 넉넉하게 잡혀 있고, 메모리 여유가 있는 시스템은 스왑을 거의 쓰지 않습니다. 다만 앞의 스래싱처럼 스왑 입출력이 몇 시간씩 계속되는 상황이라면 수명보다 성능 문제가 먼저 드러나므로, 그 자체로 RAM이나 워크로드를 조정해야 한다는 신호로 보면 됩니다. 수명이 신경 쓰인다면 smartctl -a(smartmontools 패키지)로 SSD의 누적 쓰기량을 가끔 확인해 볼 수 있습니다.

스왑 파일을 없애거나 되돌리는 방법

스왑 파일이 더는 필요 없거나, 위 작업 중 무언가 꼬여서 원래대로 돌리고 싶다면 만든 순서를 거꾸로 밟습니다.

sudo swapoff /swapfile
sudo sed -i.bak '\|^/swapfile[[:space:]]|d' /etc/fstab
sudo rm /swapfile
sudo findmnt --verify

swapoff에서 Cannot allocate memory가 난다면 앞에서 설명한 대로 메모리를 먼저 확보합니다. fstab 줄을 지우기 전에 파일부터 지우면 안 됩니다. 파일이 없는데 fstab에 줄이 남아 있으면 부팅 때 해당 스왑 유닛이 실패합니다. 스왑은 부팅을 막는 필수 항목이 아니라 대개 경고와 함께 부팅이 계속되지만, 로그에 계속 실패가 남고 다음에 fstab을 고칠 때 혼란의 원인이 됩니다. 위 sed 명령은 /etc/fstab.bak에 원본을 남기므로 잘못 지웠다면 그 파일로 되돌리면 됩니다.

swappiness를 바꿨다면 /etc/sysctl.d/99-swappiness.conf를 지우고 sudo sysctl --system을 실행하거나 재부팅하면 기본값 60으로 돌아갑니다. zram 패키지를 설치했다면 sudo apt purge zram-tools 또는 sudo apt purge systemd-zram-generator 후 재부팅합니다.

스왑을 정리한 뒤에도 메모리 부족이 반복된다면 다음으로 볼 것은 어떤 프로세스가 메모리를 쓰는지입니다. ps, top, journalctl 같은 기본 진단 명령은 우분투 필수 명령어 글에 정리되어 있습니다.