우리는 앞서 메모리의 침입을 막기위해 Base, Limit 레지스터를 이용한 보호 방법을 알아봤다.
그 과정에서 CPU에서 취급하는 논리주소와 실제 메모리에서 다루는 물리주소의 차이를 해결하는 MMU도 확인했다.
해당 글에서는 앞서 살펴본 내용을 바탕으로 본격적으로 메모리 할당 방식을 설명한다.
우리가 앞에 글에서 살펴본 방식으로 가장 간단한 방식이다.
프로세스의 메모리를 가변 크기의 파티션(공간)에 연속적으로 메모리를 할당해주는 방식이다.
운영체제는 메모리에서 사용가능한 부분과 사용중인 부분에 대한 정보를 테이블로 가지고 있는다.
사진의 파란색 부분이 사용가능한 메모리 블록(hole)이다.
가변 파티션의 그림을 다시 살펴보자.
마지막 상황인 process 9
와 process 2
가 올라와 있는 상황에서,
처음에 올라가 있던 process 8
이 다시 요청을 보냈다.
하지만 process 8
이 들어갈 만한 공간이 없어보인다.
이 요청을 어떻게 처리해야 할까?
위와 같은 경우는 어떻게 처리해야 할까?
분명 메모리에는 100MB의 사용 가능한 공간이 있지만 80MB의 공간을 가지는 프로세스가 들어오지 못하고 있다.
메모리가 연속적으로 할당되고 해제되는 작업이 반복되다 보면, 어떤 가용 공간은 너무 작은 공간이 돼버리는 것을 외부 단편화라 부른다.
외부 단편화로 인해 앞서 살펴본 예시와 같이 메모리의 공간이 넉넉하더라도 프로세스에게 할당해줄 수 없는 상황이 발생할 수 있다.
메모리를 연속적으로 할당해주는 방식은 외부 단편화를 피할 수 없다.
압축이란 메모리의 사용중인 공간을 한 쪽으로 몰아넣고,
메모리의 사용 가능한 공간을 다른 한 쪽으로 몰아넣는 방법이다.
메모리 접근 위치가 바뀌기 때문에 CPU의 동작을 완전히 중단시킨 후에 해야 하는 비용이 매우 많이 드는 방법이다.
프로세스의 논리 주소 공간을 여러 개의 고정된 크기의 비연속적인 공간으로 나누고
메모리에 비연속적으로 할당하는 방식이다.
컴퓨터 시스템에서 가장 일반적으로 사용하는 방법이다.
페이징은 연속 메모리 할당을 괴롭히는 두가지 문제인 외부 단편화와 압축에 대한 문제를 피할 수 있다.
먼저 논리 메모리를 그림과 같이 페이지라 불리는 같은 크기의 블록으로 나눈다.
물리 메모리도 프레임이라 불리는 같은 크기의 블록으로 나눈다.
그리고 프로세스의 페이지는 물리메모리에서 사용 가능한 프레임에 할당된다.
(페이지 테이블은 'MMU의 역할'에서 살펴본다.)
이 그림을 다시 확인해보자.
왼쪽과 같이 기존에는 10이라는 값에 접근하려면 14번째 주소에 접근하면 됐다.
하지만 오른쪽과 같이 페이지로 나뉘었을 때 10이라는 값에 접근하려면 어떻게 해야 할까?
논리 주소의 변화가 생겨야 한다.
논리주소가 페이지 번호(p)와 오프셋(d)을 가지면 효율적으로 접근할 수 있을 것이다.
예를 들어 페이지 번호 1 | 오프셋 1
이라는 논리주소로 접근하면 효율적일 것이다.
앞의 글에서 "MMU가 논리주소를 실제 메모리의 물리 주소로 바꿔준다"고 언급했다.
앞서 살펴본 논리주소에서 물리주소를 변환하려면 다음과 같은 과정을 거치면 된다.
이 과정에서 페이지 테이블이 등장한다.
페이지 테이블에 논리주소의 페이지 번호로 접근하여 물리 주소의 프레임 번호로 변환한다.
오프셋(d)은 변하지 않기 때문에 유지되는 것을 확인할 수 있다.
궁금한 점
페이지 테이블은 레지스터인가?
페이지 개수가 많아지면 레지스터로 감당 가능한가?
그러면 물리 메모리에 페이지 테이블을 저장하나?
일단 이 글에서는 호기심으로 남겨두자. 다음 글에서 자세히 살펴본다.
페이지의 크기는 하드웨어에 의해 정해진다.
페이지의 크기는 2의 거듭제곱으로 일반적으로 4KB부터 1GB까지 컴퓨터 아키텍처에 따라 다양한 크기를 가진다.
페이징을 통해 외부 단편화와 압축의 필요성을 없앴다.
하지만 페이징은 내부 단편화가 발생한다.
페이지의 크기를 100MB로 설정했다고 가정해보자.
이 상황에서 80MB의 프로세스를 메모리에 올리면 20MB 크기의 공간이 낭비된다. 이것이 내부 단편화이다.
내부 단편화를 최소화하는 방법으로 페이지 크기를 줄이는 방법이 있다.
하지만 페이지 크기를 줄일수록 페이지 테이블의 크기가 커지게 되며 공간이 낭비된다.
적절한 페이지의 크기를 정해야 한다.
페이지 크기는 프로세스, 데이터, 메인 메모리가 커짐에 따라 함께 커져왔다.
일반적인 페이지의 크기는 4KB 또는 8KB를 사용한다.
어떤 CPU나 OS 커널은 여러 개의 페이지 크기도 허용한다. (Windows, Linux)
페이징의 가장 중요한 특징은 메모리에 대한 프로그래머의 인식과 실제 내용이 다르다는 것이다.
프로그래머는 메모리에 올라간 프로그램이 하나의 연속적인 공간으로 인식하지만,
실제로는 프레임 단위로 분산되어 있다.
이 글에서 가변 분할 방식인 가변 파티션과 고정 분할 방식인 페이징에 대해서 알아봤고, 두 방식에서 일어나는 단편화에 대해서 알아봤다.
하지만 페이징과 페이징 테이블에 대한 궁금한 점들이 남아 있다.
다음 글에서 페이징에 대해서 더 자세하게 알아본다.
사진 출처
https://code-lab1.tistory.com/54
http://bucarotechelp.com/computers/architecture/76080801.asp
https://copycode.tistory.com/98