- 하나의 프로세스만 동작
단점
- 매 시점 하나의 프로그램만 동작하기 때문에 자원 낭비
- 가상 메모리를 사용하지 않아 프로세스가 OS를 공격 할 수 있음
- 프로세스는 메모리가 공유되는 것을 알지 못함
- 프로세스의 수/위치에 무관하게 프로그래밍
- 다른 프로세스나 OS의 메모리(데이터)를 읽거나 수정하지 못함
- 물리 메모리 자원의 낭비 방지(물리 메모리 단편화 등)
- 상호 협력하는 프로세스간의 메모리 공유가 가능해야 함
- Byte 단위의 주소로 접근되는 메모리 주소 공간
- Code, Data, Stack, Heap등 프로세스가 동작하는데 사용하는 컴포넌트(segment)가 위치하는 주소 공간
- 정적 컴포넌트: code, data(전역 변수)
- 동적 컴포넌트: stack, heap
- OS는 개별 프로세스에 자신만의 privata한 주소공간을 제공
- 프로그램 컴파일 시점에서는 얼마만큼의 메모리를 사용할지 알지 못함
- 정적 메모리 할당은 최소한으로 이루어져야 함
-> 최대 메모리 사용량만큼 할당하는 것은 메모리 낭비
- 프로시져가 얼만큼 호출될지 알 수 없음
- 지역변수의 메모리 공간은 호출마다 할당됨
- linked list, tree 등등
- 함수 호출 시 지역변수는 stack 에 동적으로 할당
- 함수 호출시 지역변수의 메모리가 할당됨
- 함수 해제시 지역변수의 메모리가 해제됨
- Heap은 가상 메모리 내 공간으로, 할당된 메모리 영역, 해제된 메모리 영역(hole)이 있음.
- 메모리 공간의 할당 해제는 임의의 순서이므로 예측 불가
- 모든 종류의 data structure에 적용 가능
- 할당 속도가 느림(stack은 expand, shrink만 하면 됨)
- Heap 공간이 조각날 수 있음(external fragmentation)
- 할당하는 메모리 공간 크기에 따른 내부 단편화(internal fragmentation)
- OS 는 heap 영역(큰 공간)만 제공하고, C lib에서 큰 공간을 쪼개서 malloc()/free()를 통해 서비스 함
- OS는 brk() 시스템 콜을 통해 heap 영역의 사이즈를 지정해 제공
int x;
int main(int argc, char *argv[]){
int y;
int *x = malloc(sizeof(int));
}
- x : static data
- main : code
- y : stack
- z : stack
- *z : heap
다수의 프로세스를 동시에 실행 가능하게 하기위해
- 프로그램 바이너리 내에 메모리 주소는 고정되어 있음
- 다수의 프로세스 사이에 메모리 충돌(같은 주소에 접근)을 해결해야 함
- 프로세스 별로 물리메모리 사용 가능 시간을 지정
- 지정된 시간이 지나면 물리 메모리의 내용을 디스크로 옮김
- 다른 프로세스를 물리메모리에 옮김
- 성능이 매우 떨어짐
- 매번 프로세스의 메모리를 디스크와 물리메모리로 복사해야되기 때문
- OS가 프로그램의 주소를 프로세스 생성 시점에 바꿔줌
- 각 프로그램이 로딩되는 물리 메모리 위치에 기반하여 명령어에서 사용하는 주소를 번역
- 다른 프로세스의 메모리를 보호해줄 수 없음
-> 프로세스가 다른 프로세스나 OS의 메모리를 읽고 수정할 수 있기 때문- 프로세스의 위치를 변경할 수 없음
-> 메모리가 부족할 경우 compaction 같은 작업이 쓰일 수 있으나 정적 재배치의 경우 불가능
- 프로세스들 사이에 보호를 제공
- CPU 하드웨어의 지원이 필요함
-> MMU(Memory management unit)- MMU가 프로세스가 사용하는 주소를 매번 동적으로 재배치해줌
-> 프로세스는 logical(virtual) 주소 사용
-> 물리메모리에 접근할때는 physical(real) 주소 사용
- OS가 동작
- 커널모드로 전환/OS의 핸들러 수행을 유발하는 구조 제공
- 특권 권한의 명령어 수행 가능
- 모든 물리 메모리 접근 가능
- 유저 프로세스 동작
- MMU가 각 유저 프로세스의 가상 주소공간 및 그 내부에 가상 메모리 제공
- OS 가 MMU에 설정한 만큼만의 메모리 접근 가능
- 모든 메모리 주소는 MMU의 주소변환을 통과
- 프로세스 생성 시 프로세스에 할당된 물리메모리의 시작 주소를 base로 설정
- 컨텍스트 스위칭시마다 base register의 값을 현재 프로세스의 것으로 변경
문제점
- 할당된 프로세스의 메모리 공간을 벗어날 수 있음
- Bounds register를 추가해 허용된 범위만 접근 가능하게 해줌
-> Base register: 주소공간의 물리메모리상 시작 주소
-> Bounds register: 해당 프로세스의 주소공간의 크기- Bound의 크기를 벗어나는 logical address를 생성하는 경우 프로그램 종료 시킴
-> Segmentation fault
- 동적 메모리에 대한 고려 부족
- Heap 영역과 Stack 영역이 얼마나 커질지 알 수 없음
-> 사용 안되는 공간의 낭비 발생- 프로세스간 메모리 공유가 불가능
- 메모리별 접근권한 관리 불가능
- Segmentation
->Segment(stack, heap, code, data) 별로 base + bound- Paging
- Code, heap, stack
- 각 segment 별로 독립적으로 expand/shrink 가능
- segment 별로 접근 권한 관리 가능
- segment 공유 가능
-> 다른 프로세스들이 일부 segment에 같은 base + bound 사용Segment table의 모습