메인 메모리
- CPU가 직접 접근할 수 있는 메모리
- 프로그램이 실행될 때 프로그램이 복사되어 메모리에 적재됨 (프로세스)
- CPU는 PC가 지시하는대로 연산을 수행한 후 메인 메모리에 데이터를 저장하거나 필요한 데이터를 요구함
각 프로세스는 별도의 메모리 공간을 갖는다
특정 프로세스만 접근할 수 있는 개별적 메모리 주소 영역을 설정한다
이 영역은 합법적인 영역이고 프로세스가 합법적인 영역만을 접근할 수 있게 하는 기능이 필요하다
- 기본 레지스터 : 가장 작은 합법 물리 메모리 주소 300040 부터 420940이라면 300040
- 상한 레지스터 : 주어진 영역의 크기 120900, 기본 레지스터에 더해서 범위의 끝 값이 됨
CPU에서 메모리 주소에 접근하려 할 때 base보다 큰 주소를 요청했는지(하한이니까), 다음으로 base + 메모리 크기보다 작은지(상한) 확인한다.
잘못 요청했는데 메모리에 접근한다면 치명적인 에러가 발생한다
1. 메모리 할당하는 방법
- 프로그램은 원래 이진 형태(바이너리)로 디스크에 저장이 되어 있다
- 그 프로그램이 메인 메모리로 적재가 된 후 프로세스가 된다
- 메인 메모리와 디스크를 왔다갔다할 수 있다
- 원시 프로그램에서 주소는 숫자가 아닌 기호 형태로 표현된다
- 이 프로그램 주소를 컴파일러가 재배치 가능한 주소에 바인딩한다
간단한 과정. 예를 들어 이 주소에서 몇 번째 뒤에 있는 주소로 이동.
- 바인딩 된 주소를 Linker 또는 Loader가 절대 주소로 바인딩한다
몇 번째 뒤가 아니라 진짜 주소를 준다
2. 메모리 주소 할당의 구분
-
메모리의 주소를 할당할 때 바인딩은 그 바인딩이 언제 이루어지는지에 따라 구분됨
- 컴파일 시간 바인딩 : 컴파일 시간에 프로세스가 메모리에 상주할 위치를 미리 알 수 있다면 컴파일러는 절대코드를 생성할 수 있음
시작 주소를 알게 되면 그 위치부터 시작해서 바인딩 되는 주소를 바로 알 수 있는 것.
시작 주소가 만약 변경이 된다면 다시 컴파일해야함
- 적재 시간 바인딩 : 프로세스가 메모리에 상주할 컴파일 시간을 알 수 없는 경우 컴파일러는 재배치 가능한 코드를 생성해야 함
재배치할 수 있는 코드를 미리 예측해서 코드를 해 두어야 함 실제 주소를 모르니까
- 실행 시간 바인딩 : 프로세스가 실행 중에 한 메모리 세그먼트에서 다른 메모리 세그먼트로 이동할 수 있는 경우 바인딩은 실행시간까지 연기되어야 함
아예 메모리 자체가 달라질 수 있으니까 바인딩을 하면 안됨 실행을 하는 그 순간까지 연기했다가 주소를 할당해야함
-
컴파일/적재시간 바인딩은 논리주소 = 물리주소
실행시간 바인딩은 논리주소 != 물리주소
-
실행시간 바인딩에서 논리주소는 CPU에서 생성한 주소(가상주소)
물리주소는 메모리 장치가 보는 주소
-
가상주소에서 물리주소로 맵핑하는 것은 메모리 관리 장치 하드웨어로 수행됨
MMU는 주소가 메모리로 전송될 때마다 모든 주소를 재배치 레지스터(기본 레지스터) 값을 추가함
유저 프로그램은 실제 물리적 주소에 절대 접근할 수 없음
연속 메모리 할당과 단편화
- 상주 운영체제용 메모리
- 유저 프로세스용 메모리
여러 유저 프로세스가 동시에 메모리에 적재되어 있는 것이 바람직함
메모리에 가져오기를 기다리고 있는 프로세스에 사용 가능한 메모리를 어떻게, 얼마나 할당해야 좋을지 고민해야함
메모리 보호
- 재배치 레지스터 : 가장 작은 물리 주소의 값을 저장
- 상한 레지스터 : 논리 주소의 범위 값을 저장
1. 다중 파티션 방식
- 메모리를 고정된 크기로 나눔
- 하나의 파티션은 하나의 프로세스를 포함
- 멀티 프로그래밍 정도는 파티션 수에 의해 결정됨
- 프로세스가 종료되어 파티션이 빈다면 입력 큐에서 다른 프로세스가 선택되어 파티션에 로드됨
2. 가변 분할 방식
- OS는 사용 가능한 메모리 부분과 사용 중인 메모리 부분을 나타내는 테이블을 유지함
- 모든 메모리는 유터 프로세스에 사용 사능하고 사용 사능한 메모리의 큰 블록을 hole이라고 칭함
3. 동적 메모리 할당 문제
: 위 사진에서 파란 부분 즉 free hole들의 리스트에서 메모리 크기가 n인 요청을 어떻게 만족시킬지?
- 최초 적합
- 첫 번째 사용 가능한 가용 공간 선택
- 집합의 시작부터 검색 또는 지난 검색에서 끝난 곳부터 검색
- 충분히 로드 가능한 hole을 찾았을 때 종료됨
- 최적 적합
- 사용 가능한 공간 중에 가장 작은 공간 선택
- 가장 효율적임 가능한 가장 작은 공간을 선택하니까 다음에 큰 요청이 들어와도 처리할 수 있는 확률이 높아짐
- 리스트가 크기 순이 아니라면 전체 리스트를 검색해서 찾아야함
- 최악 적합
- 가장 큰 가용 공간 선택
- 할당 후에 남은 공간이 충분히 커서 다른 프로세스들이 사용할 수 있어야 함
- 크기 순이 아니라면 전체 리스트 검색해야 함
4. 단편화
: 공간 중에 일부가 사용되지 못하게 되는 부분
- 최초, 최적 적합은 외부 단편화가 발생함
- 외부 단편화 : 분할된 hole을 합치면 로드할 수 있는데 연속적이지 않은 경우
- 총 메모리 저장 용량과 평균 프로세스 크기에 따라 외부 단편화는 사소하거나 중요한 문제일 수 있음
해소 방법 : 물리 메모리를 고정 크기 블록으로 나누고 블록 크기에 따른 정수배로 메모리 할당
- 내부 단편화 : 프로세스에 할당된 메모리가 요청된 메모리보다 약간 클 수 있고 그때 남는 부분
해결 방법 - 압축
- 사용 가능한 모든 메모리를 하나의 큰 블록으로 만들도록 메모리를 모음
- 재배치가 가능하고 실행 시간에 수행되는 경우만 가능
- 압축이 가능할 경우 비용 결정이 필요(비용이 많이 듬)
- 프로세스를 한 쪽 끝으로 모음
5. 페이징
- 프로세스의 물리주소 공간이 연속적이지 않아도 사용할 수 있도록 하는 메모리 관리 체계
- 외부 단편화 문제를 해결
페이징 방법
- 물리 메모리를 프레임이라 하는 고정 크기 블록으로 나눔
- 논리 메모리를 페이지라고 하는 동일 크기 블록으로 나눔
- CPU에 의해 생성된 모든 주소는 페이지 번호, 페이지 오프셋 두 부분으로 나뉨
- 페이지 번호 : 페이지 테이블 인덱스
- 페이지 테이블 : 물리 메모리에 있는 각 프레임의 기본 주소 포함. 프레임의 기본 주소가 오프셋과 결합되어 물리 메모리 주소 정의함
-
논리 주소 공간 사이즈가 2m, 페이지 사이즈가 2n 바이트라고 할 때 페이지 번호는 논리주소 상위 m-n 비트이고 페이지 오프셋은 하위 n비트
-
외부 단편화는 없으나 내부 단편화가 존재함
-
평균적으로 프로세스 당 반 페이지의 내부 단편화를 예상함
-
그렇다면 페이지 크기가 작은게 좋은가? 페이지 크기가 작으면 페이지 개수가 늘어나고 페이지 테이블의 크기가 반비례로 커짐
하드웨어 지원 -TLB
페이징 메모리 보호
- 페이지 읽기 - 쓰기 또는 읽기 전용 비트
- 유효 - 무효 비트
- 유효로 설정되면 관련 페이지가 프로세스의 합법적인 페이지임을 나타냄
- 무효로 설정되면 그 페이지는 프로세스의 논리 주소 공간에 속하지 않는 것을 나타냄
공유 페이징
장점 : 공통 코드를 공유할 수 있음