메모리 관리의 개요
static allocation
정적 할당 - 프로그램 시작 이전에 할당
컴파일 타임에 결정
dynamic allocation
동적할당 - 컴퓨터 과학에서 동적이란 runtime을 뜻함
요청이 오면 heap에 할당
프로그램 실행시 미래에 사용될 메모리의 양을 정확히 알 수 없기 때문에
범용 os가 지원함 운영체제의 기능임
OS에서 메모리 관리란?
다수의 프로세스를 위해서 user part의 메모리를 분할하는 기능 - os가 동적으로 메모리 관리
어떻게 효율적으로 할까 - 요구사항
relocation
- 재배치 가능하도록 관리해야함 메인메모리는 여러 프로세스가 동시에 사용하므로
1 프로그램 컴파일, 코딩시에 프로세스가 메모리의 어느 위치에 올라갈지 예측 불가능
2 어느 위치에 올라가더라도 이동 가능성이 있음 - cpu효율을 높이기 위한 멀티프로그래밍 과정에서 위치는 계속 바뀜
3. 상대적인 주소를 사용하여 os가 base register를 이용해서 절대주소를 결정함 이에따라 하드웨어적인 지원도 필요

protection
- 각 프로세스는 다른 프로세에게 방해 받으면 안된다.
할당받은 메모리 주소만 참조할 수 있도록 보호해야 한다.
bound register를 넘어가면 운영체제가 개입해서 중지
절대 주소는 예측 불가능하기 때문에 프로세스에 의해서 발생된 메모리 레퍼런스는 runtime에 정해져야 하고 이 메모리의 bound는 하드웨어 레벨에서 관리되는게 빠르고 쉽다. ex) bound register, base register

sharing
다수의 프로세스가 동일한 프로그램을 실행하고 있다면 page를 계속 만드는 게 아니라 같은 카피본을 엑세스하게 할 수 있도록 허용 - 커널 코드도 sharing의 일종임

logical oraganization
프로그램 중에서 코드는 수정이 불가하지만 실행 가능한 부분이고 heap이나 stack은 read, write되지만 실행되진 않는 데이터이다. 이런식으로 속성이 다른 데이터들을 모듈단위로 관리하면 메모리 관리를 효과적으로 할 수 있다.
프로그램이 사용할 메모리 주소에서 stack과 heap의 구조를 아래처럼 만들어 stack에선 동적으로 실행되가는 함수의 포인터 스택을, heap에선 동적 할당되는 데이터들을 효과적으로 저장할 수 있다.

physical organization
주기억 장치와 보조기억 장치로 나누어 적은 메모리로 더큰 요구사항을 처리할 수 있음 - os가 알아서 관리
프로그램을 모듈화해서 꼭 필요한 부분만 disk->메모리로 ex) 게임 맵 로드

주소의 타입
symbolic address
코드레벨에서 변수나 상수들이 가지는 주소
logical address
상대주소 - 프로그램 관점에서의 주소 0 부터시작
symbolic address에서 컴파일러에의해 logical oraganization이 적용된 주소 stack, heap나눠짐
실제 메모리에 있는 주소가 아님 - virtual address
일단 다 같은 개념으로 보자
physical address
절대주소 - 메인 메모리 관점에서 프로그램들이 가지는 주소
런타임에 logical address가 바뀌어서 사용됨

mmu가 변환해줌 런타임에 실제 물리적 주소가 정해지기 때문에 동적 메모리 관리라고 불림
예시
밑의 소스코드는 symbolic 주소를 가지고 그 주소는

ebx 레지스터가 x의 주소를 가지고 있다고 가정할 때 다음과 같은 logical address로 바뀐다

런타임에 os 에의해 메인 메모리에서 위 메모리들이 위치할 주소가 결정되고 이는 physical address이다.

이처럼 OS와 컴파일러가 알아서 logical address를 physical address로 바꾸는 작업 같이 사용자 입장에서 보일 필요없는 컴퓨터 작업의 특성을 'transparent'라고 한다.
OS는 어떻게 메모리 관리를 하는가
fixed partitioning (고정분할 방식)
메모리를 일정한 숫자로 분할하고, 분할된 메모리의 각 구역을 하나의 프로세스가 차지하는 방법

장점 - 프로세스가 남는 partition을 결정하면 되므로 구현이 굉장히 쉬움
단점
위의 그림처럼 4구역으로 나눈다고 하면 메모리에 위치할 수 있는 프로세스의 수가 4개로 제한됨 - 멀티 프로그램의 숫자제한
파티션의 크기도 제한이 있어 더 큰 메모리 요청이 오면 서비스 할 수 없음 - 초기에는 프로그램을 분할해서 사용함
실제 서비스하는 프로세스의 메모리가 분할된 구역의 메모리 크기보다 작으면 남은 메모리가 낭비됨 - 내부 단편화(internel fragmentation)
-> 프로세스가 사용할 메모리 크기를 런타임에 결정하자 = 동적 분할 방식
dynamic partitioning (동적 분할 방식)
요청된 프로세스가 메인메모리 어디에 위치할지 런타임에 os가 결정하는 방식

os가 적절한 메모리 위치에 프로세스를 위치시켜 메모리 낭비를 줄임 = 내부 단편화 해결
하지만 swap out된 프로세스 자리에 빈 공간이 생겨 이로 인한 메모리 낭비가 생김 = externer fragmentation - 프로세스의 partition 밖에 있다고 해서 외부단편화
-> os가 계속해서 외부 단편화로 생긴 공간으로 프로세스를 옮겨서 해결 = memory compaction(디스크 조각모음이랑 같음)
외부단편화가 많이 발생할 수록 더 많은 압축이 일어남 - 압축으로 인한 overhead 발생
세가지 동적 분할 방법
frist fit - 메모리 첫 주소부터 순회하며 프로세스가 가용될 수 있는 위치를 찾음
second fit - 마지막으로 사용한 메모리 주소부터 순회하며 프로세스가 가용될 수 있는 위치를 찾음
best fit - 외부단편화가 가장 적게 발생할 수 있는 위치를 찾음
best fit이 제일 좋아 보이지만 크기를 비교해가며 제일 적절한 위치를 찾는 비용과 그로 인해 가장 작은 외부단편화가 발생하면 그만큼 compaction을 자주 발생하게 하므로 제일 안좋음

buddy allocation
정적, 동적 분할 방식을 혼합하여 사용하는 방식
요청이 오면 가장 fit한 메모리 블럭을 계산하여 할당함 그 메모리 블럭은 2^k word 임
2의 지수 승의 메모리를 서비스해줌
2^(k-1) < requset < 2^(k)가 만족하는지 봄
ex) 만약 k가 6이고 단위가 kbyte라면 메모리 블럭은 2^6 = 64kb 이고 request된 메모리 크기가 7kb이라면 만족하지 않음
-> 만족할 때 까지 64kb를 반씩 나누고 최적의 크기를 찾음 k가 3일 때 7kb가 2^3 - 1으로 만족하므로 그 블록에 할당함

2^k의 크기를 가진 메모리 블럭을 할당한다는 점에서 정적할당의 장점과
그 크기와 위치를 런타임에 계산한다는 점에서 동적할당의 장점을 동시에 활용한다.
블록을 다 사용했으면 다시 나눠진 다른 블록과 합쳐서 가용 가능한 메모리의 크기를 다시 크게 만들어 준다.

'CS > OS' 카테고리의 다른 글
| 메모리의 기본 단위와 저장, 주소 데이터의 저장 (0) | 2022.10.14 |
|---|---|
| 분산 적재 방식 (0) | 2022.06.01 |
| Deadlock Avoidance (0) | 2022.05.27 |
| Dining Philosophers Problem - 식사하는 철학자 문제 (0) | 2022.05.27 |
| Dead Lock - Resource-Allocation Graph (0) | 2022.05.27 |