OS(10) - Main Memory Management
OS 관련 포스팅
- OS(1) - Introduction
- OS(2) - Interrupt-Based System
- OS(3) - Process Management
- OS(4) - CPU Scheduling
- OS(5) - Thread
- OS(6) - Classical Synchronization Problems
- OS(7) - Deadlock
- OS(8) - Monitor
- OS(9) - Midterm
- OS(10) - Main Memory Management
- OS(11) - Contiguous Memory Allocation
메모리 역사
- Core memory
→ 반지 모양의 철심에 자성 물질을 바른 뒤 전기 흘려 자기장이 발생해 순간적으로 자석이 되는 원리를 이용해 메모리를 만듦 - 진공관 메모리
→ 1950s ~ 1960s, 손가락 3-4개 정도의 크기로 1bit 저장시 4-5개 필요 - 트랜지스터 메모리
→ 1960s ~ 1970s, 반도체 칩 안의 소자로 손톱만한 크기
→ 1bit 저장시 4-6개 필요 - 결국,
공간을 많이 차지해 큰 메모리를 저장하기가 힘듦 - 집적회로 메모리(현재)
→ SRAM: 주로 캐시 메모리 만들 때 사용
→ DRAM: 메인 메모리 만들 때 사용
언제나 부족한 메모리
-
메모리 용량은 1970s(64KB)에서 현재(수GB)로 늘어났지만,
프로그램의 크기도 증가해 메모리는 여전히 부족함
→ 과거(1960s)의 메모리 관리가 여전히 중요한 이유 -
메모리의 효과적인 사용
→ 메모리 낭비 없애기
→ virtual memory(가상 메모리): 실제 물리적인 memory보다 크게 보이도록 하는 기술
프로그램을 메모리에 올리기
-
메모리 구조
→ address: cpu가 읽고자하는 memory의 주소
→ data: 해당 주소에 있는 내용을 cpu에 전송(양방향) - 프로그램 개발
- source file: high level language 또는 assembly language
→ high level language로 코드 작성
→ compiler가 compile하면 기계어로 번역됨
또는,
→ assembly language로 코드 작성
→ assembler가 assemble하면 기계어로 번역됨 - object file: compile 또는 assemble 결과 = 기계어
→ 유용한 함수들을 모아놓은 library와 object file을 linker가 연결(link)
= 실행 파일(exe file) - executable file: 실행 파일
→ 하드 디스크에 들어감
→ 프로그램을 실행하려면 loader가 main memory에 적재(load)
→ ‘code + data + stack’ 으로 구성
e.g.) ‘a와 b 중 더 큰 수를 구하라’에서
a, b는 data, 더 큰 수를 구하는 것은 code,
함수 호출시 돌아오는 주소 저장 또는 지역 변수를 저장하는 것은 stack
- source file: high level language 또는 assembly language
- 실행 파일을 메모리에 올릴 때,
몇 번지의 메모리에 올릴지 → loader가 결정
메인 메모리에 여러 process가 올라와 있다면 → 메모리 번지 변화 → MMU사용 - MMU(Memory Management Unit)
→ CPU와 memory 사이에 존재
→ base, limit, relocation register 존재
→ CPU에서 나온 address가 바로 memory로 가는 것을 방지(memory 보호)
→ 실행 중인 process가 address를 침범하는지 수시로 감시
e.g.) main.exe가
0번지(→ logical address: CPU가 보내는 주소)에서 실행하도록 프로그래밍 되어있는데, 실행 가능한 메모리는 500번지(→ physical address: 실제 메인 메모리로 가는 주소)가 비어있다면,
OS가 MMU의 relocation register 값을 500으로 변경함
즉, CPU가 봤을 땐 0번지에서 실행, 실제로는 500번지에서 실행되도록 함
(→ address translation)
메모리 낭비 방지
1. Dynamic Loading(동적 적재)
- 현대 OS의 처리 방식
- 프로그램 실행에 반드시 필요한 routine/data만 메모리에 적재(load)
- 오류처리, 버퍼 용량, java의 class 등이 항상 다 사용되는 것 아님
- ‘필요할 때’ 해당 부분을 메모리에 올림
- 과거에는 Static Loading(정적 적재)를 많이 했음
2. Dynamic Linking(동적 연결)
- 여러 프로그램에 공통으로 사용되는 library를 메모리에 중복해 올리면 메모리 낭비 발생
- 과거의 Static linking(정적 연결)의 경우, compile후 실행 파일 만들기 전에 link가 일어나 memory 낭비가 있었음
- Dynamic Linking(동적 연결)은 common library를 제외한 나머지 부분을 memory에 load 후, 실행할 때 lib를 load해 link
- library routine 연결(link)을 실행(load)할 때로 미루는 방법임
→ Linux: shared library 확장자 .so(shared object)파일
→ Windows: Dyanamic Linking Library(DLL) 확장자 .dll파일
3. Swapping
- main memory에 적재되어 있지만, 현재는 사용하지 않고 있는 process image를 backing store로 몰아냄
- backing store
→ 하드 디스크의 일부분으로 실행파일이 저장되어있는 부분(→ file system)과는 다른 곳
→ 대략 main memory 정도의 크기면 됨 - swapping되어 backing store에 들어가면, 해당 main memory 공간은 비워지고 다른 process가 들어갈 수 있게 됨
- backing store에서 main memory로 복귀시 이전과는 다른 자리에 들어가지만, relocation register를 사용하므로 적재 위치는 무관함