대상: 전공자 · 정보처리기사 취득자 | 목적: 인프라 직무 기술 면접 대비 중요도: ★★★ 최빈출 · ★★ 자주 출제 · ★ 기본 개념
답안 프로세스의 논리 주소 공간과 물리 메모리를 분리하여, 프로세스 전체가 메모리에 없어도 실행할 수 있게 하는 기법입니다. 이점은 ① 물리 메모리보다 큰 프로그램 실행 가능, ② 각 프로세스가 필요한 부분만 메모리에 올라가므로 더 많은 프로세스를 동시에 수용(멀티프로그래밍 정도 향상), ③ 프로세스 간 완전한 주소 공간 격리와 보호, ④ 라이브러리 공유·COW 같은 메모리 공유 최적화, ⑤ 프로그래머가 메모리 크기를 신경 쓰지 않는 프로그래밍 편의입니다. 구현은 요구 페이징이 표준입니다.
관련 개념 논리/물리 분리, 요구 페이징, 지역성(성립 근거), 주소 공간 격리
답안 요구 페이징은 페이지를 미리 올리지 않고 실제로 접근할 때 메모리에 적재하는 방식입니다. 접근한 페이지가 메모리에 없으면(페이지 테이블 유효 비트 0) MMU가 페이지 폴트 트랩을 발생시키고, 커널이 ① 유효한 접근인지 검사(아니면 SIGSEGV) → ② 빈 프레임 확보(없으면 페이지 교체) → ③ 디스크에서 해당 페이지를 읽어 프레임에 적재 → ④ 페이지 테이블 갱신(유효 비트 1) → ⑤ 폴트를 일으킨 명령을 재실행합니다. 디스크 I/O가 포함되므로 페이지 폴트는 정상 메모리 접근보다 수만~수십만 배 느려, 폴트율이 성능을 좌우합니다.
관련 개념 유효/무효 비트, 트랩, 명령 재실행, 실효 접근 시간(EAT) 계산, major/minor fault
답안 FIFO는 가장 먼저 들어온 페이지를 교체합니다. 구현이 큐로 간단하지만 오래된 페이지가 자주 쓰이는 페이지일 수 있고, 벨레이디의 모순이 발생합니다. OPT(최적)는 앞으로 가장 오랫동안 사용되지 않을 페이지를 교체하며 폴트가 이론적 최소지만 미래를 알아야 해서 구현 불가능하고, 다른 알고리즘의 평가 기준으로 씁니다. LRU는 가장 오랫동안 사용되지 않은 페이지를 교체합니다. 과거로 미래(지역성)를 근사해 OPT에 가까운 성능을 내지만, 엄밀한 구현(카운터나 스택)은 모든 접근마다 갱신이 필요해 비싸므로 실제 OS는 참조 비트 기반 근사 LRU(clock)를 씁니다. 참조 문자열로 폴트 수를 세는 계산 문제가 단골입니다.
관련 개념 참조 문자열 계산, 벨레이디의 모순(FIFO), clock(second chance), LRU 구현 비용
답안 프레임 수를 늘렸는데 페이지 폴트가 오히려 증가하는 직관에 반하는 현상으로, FIFO에서 발생합니다(예: 참조열 1,2,3,4,1,2,5,1,2,3,4,5는 프레임 3개일 때 9회, 4개일 때 10회 폴트). LRU나 OPT 같은 스택 알고리즘(프레임 n개일 때 메모리 내용이 n+1개일 때 내용의 부분집합이 되는 성질)에서는 발생하지 않습니다. FIFO는 페이지의 사용 여부와 무관하게 교체하기 때문에 이런 역전이 생깁니다.
관련 개념 스택 알고리즘, 부분집합 성질, FIFO의 한계
답안 스래싱은 프로세스들이 실행보다 페이지 폴트 처리(스왑 인/아웃)에 대부분의 시간을 쓰는 상태입니다. 원인은 멀티프로그래밍 정도가 과해 각 프로세스가 필요한 최소 프레임(워킹셋)조차 확보하지 못하는 것입니다. 악순환이 특징적입니다: 폴트 증가 → CPU 이용률 하락 → OS가 이용률을 높이려 프로세스를 더 투입 → 프레임 부족 심화 → 폴트 폭증. 해결은 ① 워킹셋 모델로 각 프로세스의 필요 프레임을 보장하고 부족하면 일부 프로세스를 중단(스왑 아웃), ② 페이지 폴트 빈도(PFF)가 상한을 넘으면 프레임 추가·하한 미만이면 회수, ③ 근본적으로 메모리 증설 또는 워크로드 축소입니다. 운영 관점에서는 vmstat의 si/so 지속 발생과 CPU 이용률 하락 조합이 스래싱 신호입니다.
관련 개념 워킹셋 모델, PFF, 멀티프로그래밍 정도, vmstat 진단
답안 워킹셋은 최근 시간 창 Δ 동안 프로세스가 참조한 페이지들의 집합으로, 지역성에 근거해 '지금 이 프로세스가 실제로 필요로 하는 메모리'를 나타냅니다. OS는 각 프로세스의 워킹셋 크기 합이 가용 프레임을 넘지 않도록 멀티프로그래밍 정도를 조절하고, 넘으면 일부 프로세스 전체를 중단시켜 스래싱을 예방합니다. Δ가 너무 작으면 지역성을 다 못 담고, 너무 크면 여러 지역성이 섞입니다. 실무에서 컨테이너 메모리 limit 설정이나 JVM 힙 사이징도 '워킹셋을 물리 메모리에 담는다'는 같은 사고방식입니다.
관련 개념 지역성 창 Δ, 프레임 할당, 스래싱 예방, RSS(Resident Set Size)
답안 균등 할당은 모든 프로세스에 같은 수의 프레임을, 비례 할당은 프로세스 크기(또는 우선순위)에 비례해 배분합니다. 교체 범위 기준으로 전역 교체는 다른 프로세스의 프레임도 빼앗을 수 있어 메모리 활용이 유연하지만 프로세스의 폴트율이 자신이 통제할 수 없는 외부 요인에 좌우됩니다. 지역 교체는 자기 프레임 안에서만 교체해 성능이 예측 가능하지만 유휴 프레임 활용이 안 됩니다. 리눅스는 기본적으로 전역 교체이며, cgroup 메모리 제한이 사실상 지역 교체 경계를 만듭니다.
관련 개념 전역 vs 지역 교체, cgroup 메모리 제한, 최소 프레임 수
답안 작은 페이지: 내부 단편화가 적고 필요한 부분만 정밀하게 적재하지만, 페이지 수가 많아져 페이지 테이블이 커지고 TLB 커버리지가 줄며 폴트 횟수가 늘어납니다. 큰 페이지: 페이지 테이블이 작고 TLB 히트율이 높아지며 디스크 I/O가 효율적(한 번에 많이)이지만 내부 단편화가 커집니다. 표준은 4KB이고, 메모리를 수십 GB 쓰는 DB·가상화 서버에서는 TLB 미스 감소를 위해 2MB/1GB huge page를 명시적으로 씁니다. 리눅스의 THP(Transparent Huge Pages)는 자동화 기능이지만 지연 스파이크를 유발할 수 있어 DB 벤더들은 비활성화를 권장하기도 합니다.
관련 개념 TLB 커버리지, huge page, THP와 DB 튜닝, 내부 단편화
답안 mmap은 파일이나 익명 메모리를 프로세스 주소 공간에 매핑하는 시스템 콜입니다. 매핑 후에는 포인터로 메모리를 읽고 쓰듯 파일에 접근하며, 실제 적재는 페이지 폴트를 통해 요구 페이징으로 이뤄집니다. read/write는 커널 버퍼(페이지 캐시)에서 사용자 버퍼로 복사가 일어나고 매번 시스템 콜이 필요한 반면, mmap은 페이지 캐시를 직접 매핑해 복사와 시스템 콜을 줄입니다. 대용량 파일 임의 접근, 프로세스 간 공유 메모리(MAP_SHARED), 라이브러리 로딩에 쓰입니다. 다만 폴트 비용과 TLB 영향이 있어 순차 대량 읽기에서는 read가 나을 수 있습니다.
관련 개념 페이지 캐시, zero-copy, MAP_SHARED/PRIVATE, 라이브러리 로딩(ld.so)
답안 커널이 페이지 회수·스왑으로도 메모리를 확보할 수 없는 극한 상황에서, oom_score가 가장 높은 프로세스를 SIGKILL로 강제 종료해 시스템을 살리는 최후 수단입니다. 점수는 메모리 사용량 위주로 계산되며, oom_score_adj로 프로세스별 가중치를 조정할 수 있습니다(-1000이면 제외). 이 배경에는 리눅스의 메모리 오버커밋 정책이 있습니다. malloc 시점에는 가상 주소만 주고 실제 페이지는 첫 접근 때 할당하므로, 약속한 메모리가 실제로 모자라는 순간이 올 수 있는 것입니다. 운영 시 dmesg에서 OOM 로그를 확인하고, 컨테이너 환경에서는 cgroup 메모리 limit 초과 시 컨테이너 단위 OOM kill이 발생합니다(쿠버네티스 OOMKilled 상태).
관련 개념 오버커밋(vm.overcommit_memory), oom_score_adj, dmesg, K8s OOMKilled, 메모리 limit
답안 페이지 캐시는 디스크에서 읽은 파일 데이터를 메모리에 캐싱하는 커널 기능으로, 같은 데이터의 재접근을 디스크 I/O 없이 처리합니다. 리눅스는 남는 메모리를 최대한 페이지 캐시로 활용하므로 free 명령에서 free(완전 미사용)가 작아 보여도 문제가 아닙니다. 캐시는 메모리가 필요하면 즉시 회수 가능하기 때문입니다. 그래서 실질 가용 메모리는 available 컬럼(free + 회수 가능한 캐시)을 봐야 합니다. "리눅스 서버 메모리가 꽉 찼어요"라는 신고의 상당수가 페이지 캐시를 오해한 것으로, 인프라 면접의 단골 실무 질문입니다. 쓰기 캐시(dirty page)는 주기적으로 디스크에 반영(writeback)됩니다.
관련 개념 buff/cache, available, dirty page와 writeback, drop_caches, vm.dirty_ratio
답안 페이지 폴트는 접근한 페이지가 메모리에 없을 때 발생하는 정상적 이벤트로, 커널이 페이지를 적재해 투명하게 해결합니다. 세그멘테이션 폴트는 프로세스가 자신에게 허용되지 않은 주소(매핑되지 않은 영역, 읽기 전용 페이지에 쓰기 등)에 접근했을 때 커널이 SIGSEGV 시그널을 보내 프로세스를 종료시키는 오류입니다. 즉 페이지 폴트 처리 과정에서 '유효하지 않은 접근'으로 판정되면 SIGSEGV가 됩니다. 원인은 널 포인터 역참조, 해제된 메모리 사용, 배열 범위 초과, 스택 오버플로우 등이며, 코어 덤프와 gdb로 디버깅합니다.
관련 개념 유효성 검사, 널 포인터, 코어 덤프, minor/major/invalid fault 구분
답안 EAT = (1−p) × 메모리 접근 시간 + p × 페이지 폴트 처리 시간 (p는 폴트 확률). 예: 메모리 접근 200ns, 폴트 처리 8ms(=8,000,000ns), p=0.001이면 EAT = 0.999×200 + 0.001×8,000,000 ≈ 8,200ns로 메모리 접근보다 40배 느려집니다. 성능 저하를 10% 이내로 유지하려면 220 ≥ 200 + p×8,000,000에서 p ≤ 0.0000025, 즉 40만 번 접근에 1회 미만의 폴트만 허용됩니다. 페이지 폴트가 얼마나 치명적인지, 왜 교체 알고리즘과 스래싱 방지가 중요한지를 수치로 보여주는 문제입니다.
관련 개념 EAT 공식, 폴트 확률의 민감도, 디스크 vs 메모리 속도 격차
답안 LRU를 저비용으로 근사하는 실용 알고리즘입니다. 프레임들을 원형 큐로 놓고 포인터(시곗바늘)가 순회하며, 각 페이지의 참조 비트를 검사합니다. 비트가 1이면(최근 사용됨) 0으로 바꾸고 한 번의 기회를 더 주며 다음으로 넘어가고, 0이면(한 바퀴 동안 미사용) 교체 대상으로 선택합니다. 하드웨어가 접근 시 참조 비트를 자동으로 1로 세팅해주므로 접근마다 소프트웨어 갱신이 필요한 엄밀한 LRU보다 훨씬 쌉니다. 변형으로 참조 비트+수정 비트를 함께 보는 개선판(NRU 계열)이 있으며, 수정된 페이지는 디스크에 써야 해서 교체 비용이 크므로 우선순위를 낮춥니다.
관련 개념 참조 비트, 수정(dirty) 비트, 원형 큐, LRU 근사
답안 ① cgroup 메모리 limit: 컨테이너가 limit을 초과하면 호스트 메모리가 남아도 OOM kill됩니다. JVM 등 런타임이 컨테이너 limit을 인식하도록 설정해야 합니다(최신 JVM은 자동 인식). ② request/limit 설계: 쿠버네티스에서 request 대비 limit이 크면 노드 메모리 오버커밋으로 이웃 워크로드 영향(noisy neighbor)이 생길 수 있습니다. ③ 스왑: 쿠버네티스는 전통적으로 스왑 비활성화를 요구해 왔으므로, 메모리 부족이 곧 OOM으로 직결됩니다. ④ 페이지 캐시 공유: 같은 노드 컨테이너들이 페이지 캐시를 공유하므로 메모리 계측(RSS vs working set)이 혼동되기 쉽습니다. 모니터링은 container_memory_working_set_bytes 기준으로 보는 것이 표준입니다.
관련 개념 cgroup v2, K8s requests/limits, OOMKilled, working set 메트릭, JVM 컨테이너 인식