메인 메모리란 ?
- 프로그램이 올라가는 거대한 바이트 배열
- 배열의 방들에는 주소를 통해 접근할 수 있음
- 메인 메모리에 올라간 프로그램은 프로세스가 됨
32 bit, 64 bit 아키텍쳐
- 운영체제의 아키텍쳐는 메인 메모리의 주소 길이에 의해 결정

멀티 프로세서에서의 메모리 접근 관리
- 각 프로세스는 자신만의 메모리 공간을 가지고 있어야 함
- 자신만의 메모리 공간을 어떻게 지정할까?
- 베이스 레지스터(Base Register)
- 해당 프로세스의 메모리 시작 위치를 저장한 레지스터
- 한계 레지스터(Limit Register)
- 해당 프로세스가 사용할 수 있는 최대 메모리 크기를 저장한 레지스터


- 즉, 멀티프로세서에서는 베이스 레지스터, 한계 레지스터를 통해 메모리 접근을 통제
운영체제의 주소 체계
- 논리적 주소(Logical Address) = 가상 주소(Virtual Address)
- 물리적 주소(Physical Address)
논리적 주소
- CPU가 사용하는 메모리의 논리적인 주소, 메모리의 실제 주소가 아님
- 메모리의 실제 주소는 프로세스가 쉽게 접근해서는 안됨
- 특히 멀티프로세스 환경에서는 다른 프로세스에 침범할 가능성이 생길 수 있음
- 프로세스는 논리적인 주소를 통해 안전하게 메모리에 접근할 수 있도록 함
- CPU는 프로세스가 마치 아래와 같은 그림처럼 메모리에 올라가 있다고 가정하고 연산 진행

- 논리적 주소는 다음과 같은 특징을 가짐
- 프로세스 내부에서 사용하며 0부터 시작
- 프로세스마다 독립적으로 가지고 있는 주소 공간
물리적 주소
- 프로세스가 실헹되기 위해 실제로 메모리에 올라가는 위치
- 메인 메모리의 실제 주소(ex. 0x FFFFFFFC)
주소 바인딩(Address Binding)
- 프로그램이 실제 메인 메모리에 어떤 위치로 올라가는지를 결정하는 것
- 프로세스의 물리적 주소가 세팅되는 과정
- 즉, 프로그램이 프로세스가 될 때, 물리적 주소를 결정하는 것
- 어떤 시점에 바인딩 하는지에 따라 3가지 유형으로 분류
Compile Time
- 코드를 컴파일 할 때 프로세스의 물리적 주소를 결정
int a; // 0x FFFF FFFC
a = 10; // 0x 3242 1232
- 주소의 위치가 바뀌면 재컴파일 해야 한다는 단점 존재
Load Time
- 프로그램을 메모리에 올릴 때, 프로세스의 물리적 주소를 결정
- 우선 컴파일 타임에 코드들을 relocatable code로 변환한 뒤, 로드 타임에 물리적 주소를 결정
- relocatable code : 메모리의 어느 위치에 두어도 상관 없는 기계 언어 코드
- 로딩 시간이 오래 걸림
Execution Time
- 프로세스 수행이 시작된 이후, 프로세스의 물리적 주소 결정
- 프로세스가 실행되면서 그때 그때 물리적 주소가 결정
- 따라서 논리적 주소를 물리적 주소로 바꿔주는 무언가가 필요함
MMU(Memory Management Unit)
- 논리적 주소를 물리적 주소로 바꿔주는 하드웨어 장치

Compile, Load Time vs Execution Time
- 결론적으로 Execution Time 바인딩을 사용한다고 함
- CPU는 물리적 주소를 알 수 없으므로, 오직 논리적 주소만 가지고 연산 진행
- Compile, Load Time 바인딩보다 안전하고 편리하게 주소를 관리할 수 있음
연속적인 메모리 할당(Contiguous Memory Allocation)
- 기존의 Base Register, Limit Register를 사용해서 메모리를 보호하려면 메모리는 반드시 연속적으로 할당되어야 함

- 이를 위해 프로세스의 메모리 공간을 항상 연속적으로 할당해주는 기법을 Contiguous Memory Allocation)라고 함

- 이 방식에서 메모리는 프로세스를 담기 위해 공간을 2가지 방식으로 분할
- 고정 분할 방식
- 메모리를 고정된 크기로 분할

- 고정 분할 방식은 내부 단편화라는 문제가 발생할 수 있음
💡 내부 단편화 : 메모리를 할당할 때 프로세스가 필요한 양보다 더 큰 메모리가 할당되어서 프로세스에서 사용하는 메모리 공간이 낭비되는 현상
2. 가변 분할 방식
- 프로세스의 크기를 고려하여 분할

- 가변 분할 방식은 외부 단편화라는 문제가 발생할 수 있음
💡 외부 단편화 : 남아있는 총 메모리 공간이 요청한 메모리 공간보다 크지만, 남아있는 공간이 연속적이지 않아 프로세스를 할당할 수 없는 현상
- 가변 분할 방식에서 프로세스의 할당, 해제를 반복하다보면 빈 공간이 여러개 생김 이때, 프로세스를 이 빈 공간들 중 어디에 할당할지 결정하는 알고리즘 3가지가 있음
단편화(Fragmentation)
- 프로세스의 할당, 해제를 반복하다보면 프로세스들이 차지하는 메모리 틈 사이에 사용하지 못할 만큼의 작은 공간들이 늘어나게 되는 현상
- 최초 적합(first-fit)
- 구멍들을 탐색하다가 할당할 수 있는 가장 첫 번째 구멍에 할당하는 것
- 최적 적합(best-fit)
- 할당할 수 있는 가장 작은 구멍에 할당하는 것
- 최악 적합(worst-fit)
- 할당할 수 있는 가장 큰 구멍에 할당하는 것
내부 단편화(Internal Fragmentation)

- 고정 분할 방식에서 발생하는 문제점
- 공간이 낭비됨
외부 단편화(External Fragmentation)

- 가변 분할 방식에서 사용되는 문제점
- 공간을 사용할 수 없음
비연속적인 메모리 할당(Noncontiguous Memory Allocation)

- 비 연속적인 메모리할당을 위해서는 Paging이라는 기법을 사용해야 함
페이징(Paging)

- 프로세스의 물리적 공간을 불연속적으로 쪼개서 관리하는 기법
- 프로세스는 페이지라는 고정 크기의 블록으로 나눠짐
- 메모리는 프레임이라는 고정 크기의 블록으로 나눠짐
- 페이지와 프레임은 page table을 통해 1:1로 매핑
- 외부 단편화 문제를 해결할 수 있음
- 논리 주소 공간과 물리 주소 공간이 완벽하게 분리되기 때문에 물리 주소를 고려하지 않고 프로그래밍 할 수 있음

- cpu는 주소를 요청할 때 위와 같이 두 가지 정보를 보내서 요청
- p 페이지와 매핑되어 있는 프레임의 d번째 위치를 찾아감

- 이 때, page table을 통해 접근하는 것은 속도적인 측면에서 아쉬움이 있을 수 있음
- 따라서 캐시 메모리인 TLB (Translation Look-aside Buffer)를 사용하여 보다 빠르게 물리 주소로 변환 가능

'CS > 운영체제' 카테고리의 다른 글
스레드 (1) | 2023.06.13 |
---|---|
데드락(Deadlock) (0) | 2023.03.26 |
스핀락, 뮤텍스, 세마포어 (0) | 2023.03.19 |
프로세스의 이해 & 프로세스간 통신 (0) | 2023.02.26 |
1강 운영체제 개요 (0) | 2023.02.21 |