콘텐츠로 이동

Copy-on-Write (COW)

Jan 27, 2026

Copy-on-Write(COW)는 fork() 시 부모의 전체 주소 공간을 복사하지 않고, 부모와 자식이 동일한 물리 페이지를 공유하다가 둘 중 하나가 페이지를 수정할 때만 해당 페이지의 복사본을 만드는 기법이다.

비유하면 공동 문서 편집과 같다. 여러 사람이 같은 문서를 읽을 때는 하나만 있어도 되지만, 누군가 수정하려면 자신만의 복사본을 만들어 수정하는 것이다.

  • fork() 시 부모의 전체 주소 공간을 복사하면 시간과 메모리 낭비가 심하다
  • 많은 자식 프로세스가 fork() 직후 exec()를 호출하여 새 프로그램을 적재한다
  • 이 경우 부모로부터 복사한 페이지는 곧바로 덮어씌워지므로 복사가 무의미하다
  • 쉘에서 명령어 실행 시마다 fork-exec 패턴을 사용한다

COW의 핵심 가정은 자식 프로세스가 부모의 데이터를 수정하지 않으면 복사할 필요가 없다는 것이다.

  1. fork() 시 부모와 자식이 동일한 물리 페이지를 공유
  2. 공유 페이지를 copy-on-write 페이지로 표시
  3. 어느 한쪽이 페이지에 쓰기를 시도하면:
    • 페이지 폴트 발생
    • OS가 해당 페이지의 복사본 생성
    • 수정하는 프로세스에게 복사본 할당
    • 원본 페이지는 다른 프로세스가 계속 사용
  4. 수정되지 않는 페이지(예: 코드 영역)는 계속 공유
fork() 직후:
┌──────────┐ ┌──────────────┐ ┌──────────┐
│ Parent │────>│ Physical │<────│ Child │
│ Process │ │ Pages │ │ Process │
└──────────┘ │ (shared, │ └──────────┘
│ CoW marked)│
└──────────────┘
자식이 page 수정 시:
┌──────────┐ ┌──────────────┐ ┌──────────┐
│ Parent │────>│ Original │ │ Child │
│ Process │ │ Page │ │ Process │
└──────────┘ └──────────────┘ └────┬─────┘
┌──────────────┐ │
│ Copy of │<─────────┘
│ Page │
└──────────────┘

부모 프로세스가 A, B, C 세 개의 페이지를 가지고 있을 때:

[Before: 자식이 C를 수정하기 전]
부모 ──> page A <── 자식
page B
page C (CoW 표시)
[After: 자식이 C를 수정한 후]
부모 ──> page A <── 자식
page B
page C copy of C <── 자식

자식이 page C에 쓰기를 시도하면 페이지 폴트가 발생하고, OS가 page C의 복사본을 만들어 자식에게 할당한다. page A와 page B는 수정되지 않았으므로 계속 공유된다.

구분fork() + CoWvfork()
페이지 공유쓰기 시 복사완전 공유 (복사 없음)
부모 상태동시 실행자식이 exec/exit까지 중단
안전성자식이 부모 영향 없음자식이 부모 주소 공간 수정 가능
사용 권장일반적 사용exec() 직전에만 사용

vfork()는 COW 없이 주소 공간을 완전 공유하므로 더 빠르지만, 자식이 부모의 메모리를 직접 수정할 수 있어 위험하다. exec() 직전에만 안전하게 사용할 수 있다.

  • 장점: 프로세스 생성 속도 대폭 향상, 메모리 효율적 사용, fork-exec 패턴에 매우 효율적
  • 단점: 쓰기 시 페이지 폴트 오버헤드 발생, 페이지 관리 복잡도 증가, 수정 빈도가 높으면 결국 대부분 복사됨