LRU (Least Recently Used) 페이지 교체

핵심 인사이트 (3줄 요약)

  1. 본질: LRU (Least Recently Used)는 메모리(RAM)가 꽉 차서 페이지를 내쫓아야 할 때, **"가장 오랫동안 사용되지 않은(Least Recently Used) 페이지를 1순위 희생양으로 삼아 교체"**하는 통계 기반의 교체 알고리즘이다.
  2. 가치: "과거에 오랫동안 안 쓴 데이터는 미래에도 안 쓸 확률이 높다"는 참조의 지역성(Locality of Reference) 원리를 가장 충실히 반영하여, FIFO의 치명적 결함인 Belady의 모순을 해결하고 실제 워크로드에서 최적 알고리즘(OPT)에 가장 근접한 완벽한 적중률(Hit Rate)을 자랑한다.
  3. 융합: 하지만 메모리에 접근할 때마다 시간을 기록하거나 링크드 리스트(Linked List)를 갱신해야 하는 $O(N)$의 거대한 오버헤드를 동반하므로, 순수 LRU는 OS 커널 레벨에서는 쓸 수 없고 하드웨어 지원을 받는 클럭(Clock / Second-Chance) 알고리즘 형태로 우회 융합되어 사용된다.

Ⅰ. 개요 및 필요성 (Context & Necessity)

  • 개념: 페이지 교체의 시점을 미래가 아닌 '과거'의 기록에 의존하는 알고리즘이다. 메모리에 있는 모든 페이지의 '마지막 참조 시간'을 추적하여, 그 시간이 가장 먼(오래된) 페이지를 가차 없이 버린다.
  • 필요성: FIFO(선입선출) 알고리즘은 먼저 들어온 놈을 무조건 내쫓았다. 하지만 먼저 들어왔어도 1초에 한 번씩 계속 쓰이는 "핵심 변수" 페이지를 쫓아내는 바람에 페이지 폴트가 터지는 멍청한 짓(Belady's Anomaly)을 반복했다. 이를 막으려면 단순히 '들어온 시간'이 아니라 **'마지막으로 사용된 시간'**을 기준으로 가치를 재평가하는 똑똑한 매니저가 필요했다.
  • 💡 비유: 옷장(RAM)이 꽉 찼을 때 헌옷수거함(디스크)에 버릴 옷을 고르는 기준과 같다. FIFO가 **'가장 먼저 산 10년 된 명품 코트'**를 버린다면, LRU는 **'산 지 1달밖에 안 됐지만 지난주부터 한 번도 안 입은 유행 지난 티셔츠'**를 버리는 현실적이고 합리적인 판단법이다.
  • 등장 배경: 이상적인 최적(Optimal) 알고리즘은 "미래에 가장 늦게 쓰일 놈"을 버리는 것이지만, OS는 미래를 볼 수 없다. 그래서 컴퓨터 공학자들은 "과거를 보면 미래를 알 수 있다"는 지역성의 원리를 빌려와, 과거의 최장 미사용 데이터를 미래의 최장 미사용 데이터로 '근사(Approximation)'하는 방식으로 LRU를 정립했다.
  [LRU 페이지 교체 알고리즘의 동작 메커니즘]

  [ 초기 상태: 빈 프레임 3개 존재 ]
  페이지 요청 순서: 1 ─▶ 2 ─▶ 3 ─▶ 1 ─▶ 4
  
  [ 메모리 큐 상태 변화 (가장 최근에 쓴 놈이 맨 뒤, 가장 안 쓴 놈이 맨 앞) ]
  1 요청: [ 1 ] 
  2 요청: [ 1, 2 ] 
  3 요청: [ 1, 2, 3 ] (여기서 가장 안 쓴 놈은 1번)
  
  1 요청: 어라? 1번을 또 쓰네? 1번을 최근 사용한 것으로 갱신! (맨 뒤로 보냄)
         [ 2, 3, 1 ] (이제 가장 안 쓴 놈은 2번으로 바뀜!)
         
  4 요청: 🚨 메모리 꽉 참! 제일 안 쓴 맨 앞의 '2'를 버리고 '4'를 넣음.
         [ 3, 1, 4 ] (폴트 발생)

[다이어그램 해설] LRU의 핵심은 "과거의 세탁(갱신)"이다. FIFO였다면 4번이 들어올 때 제일 처음 들어온 1번을 버렸을 것이다. 하지만 LRU는 1번이 방금 전에 다시 쓰였다는 사실을 인지하고 1번의 생명(수명)을 연장해 주며, 그동안 한 번도 안 불린 2번을 가차 없이 처단한다. 이 작은 차이가 캐시 히트율(Hit Rate)을 수십 배 끌어올린다.

  • 📢 섹션 요약 비유: 회사에서 구조조정을 할 때, FIFO는 "입사한 지 가장 오래된 부장님"을 자릅니다. 부장님이 회사 핵심 인재라도 예외는 없습니다. LRU는 "입사일과 상관없이, 최근 1달 동안 실적이 가장 없는(안 쓰인) 사람"을 자릅니다. 철저한 성과(참조) 주의 룰입니다.

Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)

순수 LRU를 구현하기 위한 2가지 끔찍한 오버헤드

LRU 알고리즘이 동작하려면 OS는 메모리에 있는 페이지들의 순위를 완벽히 매겨야 한다. 이를 소프트웨어로 구현하는 방법은 두 가지지만, 둘 다 OS에겐 악몽이다.

1. 카운터 (Counter / Timestamp) 구현

  • 원리: 각 페이지 테이블 항목에 시간(Time) 필드를 추가한다. CPU가 메모리를 참조할 때마다 현재 시간(클럭)을 그 필드에 적는다.
  • 교체 시: 램이 꽉 차면, OS는 모든 페이지의 시간 필드를 하나씩 다 까보고 가장 작은 값(가장 옛날 시간)을 가진 놈을 찾아 죽인다.
  • 한계: $O(N)$의 탐색 시간이 걸린다. 100만 개의 페이지를 다 뒤져야 하므로 1ms 안에 교체를 끝내야 하는 OS 스케줄러가 버티지 못한다.

2. 스택 (Linked List Stack) 구현

  • 원리: 페이지를 더블 링크드 리스트(Doubly Linked List)로 관리한다. 페이지가 참조될 때마다 그 페이지의 노드를 끊어내서 무조건 리스트의 맨 위(Top)로 끌어올린다.
  • 교체 시: 리스트의 맨 바닥(Bottom)에 있는 놈이 제일 안 쓰인 놈이므로 묻지도 따지지도 않고 바로 죽인다. ($O(1)$ 탐색).
  • 한계: 탐색은 빠르지만, CPU가 메모리를 참조할 때마다 포인터 6개를 바꿔 끼우는(링크드 리스트 업데이트) 연산을 동반해야 한다. 메모리 엑세스는 1나노초 단위인데 이 오버헤드는 배보다 배꼽이 100배 큰 짓이다.
  ┌────────────────────────────────────────────────────────────────────────┐
  │         LRU의 스택(Linked List) 구현 시 발생하는 연산 병목 시각화      │
  ├────────────────────────────────────────────────────────────────────────┤
  │                                                                        │
  │   [ 현재 스택 상태 ] (Top이 최근, Bottom이 옛날)                       │
  │   TOP ─▶ [Page 3] ─▶ [Page 5] ─▶ [Page 1] ─▶ [Page 2] ◀─ BOT           │
  │                                                                        │
  │   [ CPU가 갑자기 Page 1을 읽음 (참조 발생!) ]                          │
  │   1. Page 1의 앞뒤 포인터(5와 2)를 서로 연결해 줌.                     │
  │   2. Page 1의 이전 노드를 NULL로, 다음 노드를 Page 3으로 변경.         │
  │   3. Top 포인터를 Page 1로 변경.                                       │
  │                                                                        │
  │   🚨 딜레마: 메모리를 읽을 때마다 OS가 이런 무거운 포인터 조작을       │
  │      소프트웨어 락(Lock)을 걸어가며 해야 한다? (시스템 마비 확정)      │
  └────────────────────────────────────────────────────────────────────────┘
  • 📢 섹션 요약 비유: 도서관(LRU)에서 책을 완벽하게 인기순으로 정리하려면, 누군가 책을 1페이지 넘길 때마다 사서가 달려와서 그 책을 뽑아 도서관 맨 앞 책장으로 옮겨 꽂아야 합니다. 책을 읽는 시간보다 사서가 책을 옮기는 시간(오버헤드)이 더 오래 걸려서 도서관이 마비됩니다.

Ⅲ. 융합 비교 및 다각도 분석 (Comparison & Synergy)

최적(OPT) vs LRU vs FIFO 의 수학적 성능 궤적

어떤 알고리즘이 스래싱을 잘 막고 페이지 폴트를 덜 내는지 비교한다.

비교 항목OPT (최적 알고리즘)LRU (최근 최소 사용)FIFO (선입 선출)
철학미래를 보고 버린다과거를 보고 버린다나이(시간)만 보고 버린다
페이지 폴트 수가장 적음 (절대적 최저치)OPT에 매우 근접함 (훌륭함)가장 많음 (쓰레기)
모순 발생없음 (Stack 알고리즘)없음 (Stack 알고리즘)발생함 (Belady's Anomaly)
실무 사용❌ 구현 불가능 (비교 잣대로만 씀)❌ OS 커널에선 오버헤드로 못 씀
✅ DB, 웹 캐시에선 표준으로 씀
❌ 안 씀

LRU의 약점: 한 번만 읽고 버리는 스캔(Scan) 작업

LRU는 "자주 쓰는 놈"을 우대하는 데 특화되어 있다. 하지만 "용량이 엄청나게 큰 파일을 처음부터 끝까지 한 번만 쭉 읽고 끝내는(Sequential Scan)" 작업이 들어오면 LRU는 완벽하게 무너진다.

  • 바이러스 백신이 10GB짜리 C드라이브를 풀 스캔했다.

  • LRU 로직은 "오! 지금 읽고 있으니 최신 데이터네!"라며 10GB어치 쓰레기 데이터를 캐시의 Top에 다 올려버린다.

  • 결과적으로 진짜 매일 쓰던 크롬, 카카오톡 메모리가 다 바닥으로 쫓겨나 삭제(Swap-out)되는 캐시 오염(Cache Pollution) 현상이 발생한다.

  • 📢 섹션 요약 비유: LRU는 방금 들어온 사람을 무조건 귀빈 대접합니다. 단골손님(크롬)이 10명 앉아있는 식당에, 지나가다 한 번 들른 관광객(풀 스캔) 100명이 우르르 들어오면, 주인이 단골을 다 쫓아내고 관광객을 앉히는 멍청한 짓을 저지릅니다. 관광객은 밥 먹고 영원히 떠나버리므로, 식당은 단골을 잃고 망합니다(캐시 파괴).


Ⅳ. 실무 적용 및 기술사적 판단 (Strategy & Decision)

실무 시나리오

  1. Clock (Second-Chance) 알고리즘: OS 커널의 현실적 타협: 리눅스와 윈도우는 무거운 진짜 LRU(Linked List)를 버리고, 하드웨어 비트를 활용한 가짜 LRU(Pseudo-LRU)를 쓴다.
    • 원리: 페이지마다 1비트짜리 Reference Bit를 둔다. CPU가 메모리를 읽으면 하드웨어가 0을 1로 바꿔준다. (포인터 갱신 오버헤드 0%).
    • 교체 시: OS 시곗바늘이 페이지를 빙빙 돌며 1이면 0으로 깎고 한 번 살려준다(Second Chance). 0이면 쫓아낸다.
    • 결과: 리스트를 갱신할 필요 없이, 가장 최근에 안 쓴 놈을 $O(1)$에 가깝게 찾아내는 현대 OS 페이지 교체의 절대 표준이 되었다.
  2. Redis 및 백엔드 애플리케이션의 LRU 아키텍처: OS 커널에서는 무거워서 못 쓰지만, Java나 C++로 짠 사용자 애플리케이션(User Space) 에서는 LRU가 만병통치약이다.
    • Redis allkeys-lru: 초당 10만 건을 처리하는 Redis는 해시 테이블(Hash Table)과 이중 연결 리스트(Doubly Linked List)를 결합하여 $O(1)$의 속도로 순수 LRU를 완벽히 구현해 냈다. 10GB 메모리가 꽉 차면 얄짤없이 꼬리에 있는 놈을 날려버려 영원히 죽지 않는 불사의 캐시 서버를 만든다.
    • LRU-K 와 ARC의 진화: 앞서 말한 "풀 스캔 시 캐시가 다 날아가는(Cache Pollution)" 버그를 막기 위해, 실무 DB(Oracle 등)는 LRU 큐를 2개 둔다. 한 번 읽은 놈은 '임시 큐'에 두고, 2번 이상 읽힌 진짜 단골손님만 '진짜 LRU 큐'에 올려주는 LRU-2 (혹은 ARC) 하이브리드 아키텍처를 짜서 완벽한 방어망을 구축한다.
  ┌───────────────────────────────────────────────────────────────────┐
  │     백엔드 아키텍트의 인메모리 캐시(Cache) 정책 설계 가이드라인   │
  ├───────────────────────────────────────────────────────────────────┤
  │                                                                   │
  │   [요구사항: 초당 100만 조회가 일어나는 쇼핑몰 상품 캐시 메모리]  │
  │                                                                   │
  │   [ ❌ 단순 FIFO 또는 Random 적용 ]                               │
  │     ▶ 판정: 히트율(Hit Rate) 50% 미만. DB 부하 폭주로 서버 즉사.  │
  │                                                                   │
  │   [ 🟡 순수 LRU (Least Recently Used) 적용 ]                      │
  │     ▶ 판정: 히트율 80% 달성. 훌륭함.                              │
  │     ▶ 약점: 심야 시간에 "전체 상품 재고 동기화 배치"가 도는 순간, │
  │             캐시가 다 털려버리고 아침에 DB가 뻗음 (Pollution).    │
  │                                                                   │
  │   [ 🚀 W-TinyLFU (Caffeine Cache 등 최신 기술) 적용 ]             │
  │     ▶ 판정: 최근성(LRU)과 빈도수(LFU)를 결합한 현대 캐시의 끝판왕.│
  │     ▶ 효과: 한 번 쓱 지나가는 배치 작업은 메인 캐시에 못 들어오게 │
  │             방어하여(Admission Window), 히트율 99%를 철통 보장!   │
  └───────────────────────────────────────────────────────────────────┘

[다이어그램 해설] 단순히 LinkedHashMap으로 LRU를 짜서 실무에 올리는 시대는 지났다. 백엔드 시스템은 항상 예상치 못한 어뷰저(크롤링 봇)나 백그라운드 스캔 작업의 공격을 받는다. 진정한 아키텍트는 LRU의 약점(최근성 맹신)을 보완하기 위해 LFU(빈도수)의 철학을 한 스푼 섞은 하이브리드 캐시 엔진(Caffeine, Guava)을 선택하여 DB를 완벽히 보호한다.

  • 📢 섹션 요약 비유: 순수 LRU는 10년 단골(자주 찾는 데이터)이든 어제 처음 온 손님이든 무조건 '어제 온 손님'을 더 우대하는 단기 기억상실증 사장님입니다. 현대의 캐시 아키텍처는 단골장부(LFU)를 따로 둬서, 어제 한 번 온 손님이 단골의 자리를 빼앗지 못하게 철저히 입구 컷(Admission Control)을 하는 똑똑한 매니저 시스템입니다.

Ⅴ. 기대효과 및 결론 (Future & Standard)

기대효과

LRU 알고리즘(또는 그 파생형인 Clock)을 메모리 시스템에 적용하면, 한정된 램(RAM) 용량으로도 미래의 데이터 접근 패턴을 90% 이상 정확히 예측해 냄으로써 페이지 폴트(디스크 I/O) 빈도를 획기적으로 줄여 시스템 스루풋(Throughput)을 수백 배 상승시킬 수 있다.

결론 및 미래 전망

LRU는 "참조의 지역성(Locality)"이라는 컴퓨터 공학의 신성한 법칙을 교체 알고리즘으로 치환해 낸 영원한 마스터피스다. 1970년대에 발명되었지만 50년이 지난 지금도 CPU의 L1 캐시부터 웹 브라우저의 이미지 캐시, CDN(Content Delivery Network)의 에지 캐시까지 모든 IT 인프라의 데이터를 버리는(Eviction) 절대 1원칙으로 군림하고 있다. 미래에는 이 LRU의 약점인 "오버헤드"와 "스캔 공격 취약점"을 해결하기 위해, 인공지능(Machine Learning)이 메모리 접근 패턴을 실시간으로 학습하여 미래에 쓸 페이지를 미리 예측해 프리패치(Prefetch)하고, 안 쓸 페이지를 알아서 밀어버리는 **'머신러닝 기반 캐시 교체(ML-based Cache Replacement)'**가 차세대 클라우드 인프라의 표준이 될 것이다.

  • 📢 섹션 요약 비유: LRU는 '과거의 통계'로 내일을 예측하는 일기예보입니다. 완벽하진 않지만 이것 없이 항해를 할 순 없습니다. 미래에는 과거 통계뿐만 아니라 기압과 바람의 방향까지 AI가 분석하여 1분 뒤의 날씨를 100% 맞춰내는 슈퍼 일기예보(AI 스케줄링)의 시대로 진화할 것입니다.

📌 관련 개념 맵 (Knowledge Graph)

개념 명칭관계 및 시너지 설명
페이지 교체 (Page Replacement)LRU가 자신의 진가를 뽐내는 잔혹한 생존 서바이벌 무대다.
참조의 지역성 (Locality)LRU 알고리즘이 "방금 쓴 놈은 나중에도 쓴다"며 맹신하고 기대는 위대한 통계적 법칙이다.
클럭 알고리즘 (Clock / NUR)LRU가 너무 무거워서 커널이 쓸 수 없자, 하드웨어 비트를 이용해 LRU를 흉내 내도록 만든 실무형 짝퉁(?) LRU다.
FIFO (First-In, First-Out)최근성(Recency)을 개나 줘버리고 들어온 순서대로 쫓아냈다가 벨라디의 모순에 빠진 LRU의 한심한 선배다.
Belady의 모순 (Anomaly)LRU는 이 모순(램 늘렸는데 느려짐)에 절대 빠지지 않는다는 수학적 면역력(Stack Algorithm)을 가지고 있다.

👶 어린이를 위한 3줄 비유 설명

  1. 장난감 상자에 장난감을 3개만 넣을 수 있는데 4번째 새 장난감이 생겼어요. 누굴 버려야 할까요?
  2. 멍청한 규칙(FIFO)은 "제일 먼저 산 1번 로봇 버려!"라고 해요. 근데 1번 로봇은 내가 매일 가지고 노는 제일 좋아하는 장난감이라 버리면 매일 슬퍼요.
  3. 똑똑한 LRU 규칙은 "산 지 얼마나 됐는지는 상관없고, 최근 한 달 동안 한 번도 안 꺼내 놀았던 먼지 쌓인 팽이를 버리자!"라고 판단하는 아주 합리적인 방법이랍니다!