🥔 Lazy Loading이란?
Lazy Loading(지연 로딩) 은 필요한 데이터나 리소스를 실제로 접근하는 순간까지 로딩을 미루는 전략이다. 이 기법은 메모리 낭비를 줄이고, 프로그램 시작 속도를 개선하며, 리소스가 실제로 사용되지 않을 수도 있는 경우 효율적인 메모리 사용을 가능하게 해준다.
운영체제에서의 Lazy Loading은 특히 가상 메모리 시스템과 페이지 폴트(Page Fault) 처리와 밀접하게 연관되어 있다.
🥔 Lazy Loading이 왜 필요한가?
- 초기 실행 속도 향상: 모든 페이지를 한 번에 로딩하지 않으므로 빠른 시작이 가능하다.
- 메모리 절약: 실제로 사용되는 페이지만 메모리에 올리므로 전체 메모리 사용량 감소.
- 디스크 접근 최소화: 사용하지 않는 데이터를 미리 로딩하지 않으므로 디스크 I/O가 줄어듬.
- 대형 프로그램에 필수적: 예를 들어, GUI 애플리케이션, 웹 서버, 운영체제 커널 등에서는 Lazy Loading이 필수적이다.
🥔 Lazy Loading 동작 방식
Lazy Loading은 일반적으로 다음과 같은 흐름으로 동작한다:
- 프로세스 시작 시, 필요한 모든 데이터를 메모리에 적재하지 않고, 페이지 테이블만 구성해둔다.
- 해당 페이지가 실제로 접근되었을 때, MMU는 페이지 테이블의 "present bit"를 확인하고, 설정되어 있지 않으면 Page Fault Exception 을 발생시킨다.
- OS의 페이지 폴트 핸들러가 디스크에서 해당 데이터를 로드하여 물리 메모리에 적재하고, 페이지 테이블을 업데이트한다.
- CPU는 중단된 명령어를 다시 실행하며, 이제는 유효한 물리 주소로 접근이 가능하다.
🥔 실제 예시: Executable Load 시
운영체제는 실행 파일을 메모리에 올릴 때 전체 텍스트, 데이터, 스택, 힙 영역을 미리 메모리에 올리지 않는다. 대신, 다음과 같이 Lazy Loading을 활용한다:
- 실행 파일의 ELF 헤더 정보만 파싱
- 각 섹션의 파일 오프셋만 기록
- 접근 시마다 Page Fault를 발생시켜 해당 섹션만 적재
이 과정을 OS에서는 demand paging이라고도 부른다.
🥔 Lazy Loading vs Eager Loading
| 항목 | Lazy Loading | Eager Loading |
|---|
| 적재 시점 | 접근할 때 로드 | 시작 시 모두 로드 |
| 메모리 사용 | 적게 사용 | 많이 사용 |
| 속도 | 초기 빠름, 중간에 느려질 수 있음 | 초기 느림, 이후 빠름 |
| 장점 | 불필요한 로드를 방지 | 전체 데이터를 바로 사용 가능 |
| 단점 | 페이지 폴트 발생 가능 | 시작 시 시간이 오래 걸림 |
🥔 구현 예시 (Pintos 기준)
Pintos Project 2~3에서는 Lazy Loading을 구현하게 되는데, 예를 들어 load_segment() 함수에서:
vm_alloc_page_with_initializer(type, upage, writable, lazy_load_segment, aux);
→ 이후 접근 시, page_fault() 함수에서 해당 핸들러(lazy_load_segment)를 호출하여 진짜 로딩을 수행한다.
🥔 장점과 유의점
✅ 장점
- 메모리 효율성 극대화
- 실행 속도 향상 (초기 로딩 시)
- 불필요한 리소스 낭비 방지
⚠️ 주의점
- 잦은 페이지 폴트는 오히려 성능 저하를 유발할 수 있다.
- 구현이 복잡하며, I/O 동기화와 예외 처리에 주의가 필요하다.
- 실시간 시스템에는 적합하지 않을 수 있다.
🥔 정리
- Lazy Loading은 실제로 필요한 순간까지 로딩을 미루는 전략이다.
- 메모리 효율성을 극대화하고, 실행 시간 단축에 기여한다.
- 운영체제에서 Lazy Loading은 가상 메모리 시스템과 페이지 폴트를 활용하여 구현된다.
- Pintos 같은 교육용 OS에서도 프로젝트 2~3에서 이를 직접 구현해보며 개념을 체화할 수 있다.