메모리는 CPU와 디스크 사이의 주기억장치로 실행 중인 프로그램 들의 프로세스의 데이터들을 저장하는 공간이다.
즉, 메모리 관리는 말 그대로 메모리를 관리하는 기법으로 한정된 크기의 메모리를 보다 효율적으로 사용하는 방법이라고 할 수 있다.
그러면 OS는 메모리를 어떻게 관리해서 보다 효율적으로 사용자가 컴퓨터를 사용할 수 있게 해주는 걸까?
메모리는 일종의 아파트로 데이터라는 입주민이 들어올 수 있는 공간이다. 그리고 데이터가 저장될 공간을 지칭하는 쉽게 말해 데이터가 입주할 아파트 호수를 주소라고 한다.
따라서 모든 프로세스는 자신이 필요한 데이터를 디스크에서 가져와 메모리에 올려 놓고 CPU로 부터 자원을 할당받아 작업을 수행하는데, 문제는 컴퓨터에서 돌아가는 프로세스가 너무 많다는 것이다.
당장 작업관리자만 켜봐도 수 많은 프로세스가 돌아가는 것을 확인할 수 있으며 해당 프로세스의 응용 프로그램의 크기들만 따져도 수백 기가는 될 것이다.
하지만 알다시피 메모리는 많아야 16기가 이하로 절대 모든 프로그램의 데이터를 가져올 순 없다. 즉, 메모리는 프로세스와 관련된 모든 데이터를 가져오는 것이 아닌 프로세스 수행 간 필요한 데이터만을 골라서 가져와 실제로 저장가능한 공간보다 많은 데이터를 사용하는 것을 메모리 관리라고 한다.
1. Dynamic Loading (동적 로딩)
단적인 예시로 프로세스의 메모리 영역은 크게 Code, Data, Stack, Heap 으로 이루어져있다. 만약 코드 실행 중 동적 변수가 사용되지 않았다면 Heap 영역을 따로 할당할 필요가 없다. 이러한 프로세스가 진행되는 루틴 중 필요한 주소 공간만을 메모리에 올리는 것을 동적 로딩이라고 한다. 동적 로딩은 OS의 라이브러리의 기능을 사용하는 것으로 현재는 가상 메모리 기법에 밀려 특수한 디바이스가 아니라면 사용되지 않는다.
2. OverLay
동적 로딩과 동일하게 프로세스 코드 실행 간 필요한 코드만 메모리에 올려서 사용하는 기법이다. 단 오버레이의 경우 OS 라이브러리 기능을 사용하는 것이 아닌 개발자가 직접 설계하는 것으로 기억장치의 기술이 지금만큼 발전하지 않던 시절 사용하던 기법이다.
3. Dynamic Linking (동적 링킹)
컴파일 시 실행에 관련된 모든 파일의 데이터를 올리는 것이 아닌 필요한 파일만 올려서 사용하는 기법이다. 흔히 우리가 코드 작성 시 특정 함수나 클래스를 사용하기 위해서는 라이브러리를 추가로 가져와야하는데 이때 필요한 라이브러리만 가져오는 것을 동적 링킹, 모든 파일을 가져오는 것을 정적 링킹이라고 한다.
4. Swapping
사용하지 않는 프로세스를 일시적으로 메모리에서 Backing Store = 보조기억장치 = 디스크로 내리는 기법이다. 보통 중기 스케쥴러인 Swapper 가 내보낼, Swap Out 할 프로세스를 선정해 Swap Out 하며 요청에 의해 다시 Swap In 을 한다. 이때 데이터가 이동하는 시간을 Swap Time 이라고 하며 아래의 가상 메모리에서 마저 설명하겠지만 주소 바인딩 정책에 따라 기존에 미리 할당 받은 물리 주소를 그대로 받거나 새로 받을 수 있다. (당연히 후자가 더 빠르다)
5. Virtual Memory (가상 메모리)
가상 메모리는 가장 널리 사용되는 메모리 관리 기법으로 OS가 메모리의 실제 주소인 물리 주소를 추상화하여 프로세스마다 물리 주소와 매핑된 논리 주소를 프로세스마다 독립적으로 할당해 주며 CPU는 프로세스의 데이터가 저장된 메모리의 물리주소가 아닌 프로세스의 논리 주소를 보게 된다.
이때 물리 주소와 논리 주소를 매핑하는 과정을 주소 바인딩이라고 하는데, 주소 바인딩은 매핑하는 시점에 따라 다음과 같이 분류할 수 있다.
1) Compile Time Binding (컴파일 시점 바인딩)
- 소스 코드가 실행 파일로 컴파일 되는 과정에서 논리 주소와 물리 주소를 바인딩
- 향후 매핑된 물리 주소를 변경할 수 없음
2) Load Time Binding (실행 시점 바인딩)
- 메모리에 데이터가 올라오는 순간 논리 주소와 물리 주소를 바인딩
- 향후 매핑된 물리 주소를 변경할 수 없음
3) Run Time Binding (실행 중 바인딩)
- 이미 매핑된 물리 주소를 프로세스 실행 중에 정책에 의해 다시 바인딩 될 수 있음
- MMU (Memmory Management Unit) 라고 하는 특정 HW 가 필요함
- 가장 보편적인 방식
그렇다면 가상 메모리는 어떤 방식으로 논리 주소와 물리 주소를 메모리에 나눠서 할당할까?
메모리의 물리 주소 공간은 OS의 프로세스 데이터가 저장된 OS 영역과 사용자가 실행시킨 응용 프로그램의 프로세스의 데이터가 저장된 User 영역으로 나눠지며 User 영역에 저장되는 프로세스의 데이터는 저장 방식에따라 연속 할당과 불연속 할당으로 나뉜다.
연속 할당은 데이터의 논리 주소의 순서대로 메모리의 물리 주소에 저장하는 것으로 고정 분할, 가변 분할 2가지로 나뉘며 불연속 할당은 순서를 따지지 않고 저장하는 것으로 Paging, Segmentaion, Paged Segmentation 3가지로 나뉜다.
고정 분할은 메모리의 물리 주소를 미리 나눈 상태로 데이터가 들어오면 크기에 따라 순서대로 저장하는 방식으로 A 와 B 처럼 크기보다 작거나 딱 맞는 경우에는 해당 위치에 저장되며 이때 남는 공간을 내부 조각이라고 한다. 반대로 y-z 사이에 주소 공간의 크기가 충분하지 않아 건너 뛰게 되는 경우 외부 조각이라고 하며 다른 말로 Hole 이라고도 한다.
가변 분할은 들어오는 데이터에 맞춰서 메모리의 주소 공간을 할당해주는 것으로 크기를 딱 맞게 할당하기 때문에 내부 조각은 발생하지 않는다. 하지만 위와 같이 남는 공간 보다 큰 프로세스 데이터가 들어오게 되면 연속적으로 데이터를 저장하기 때문에 마찬가지로 외부 조각이 발생한다. (참고로 우리가 아는 디스크 조각 모음은 대상이 디스크 즉 보조 기억 장치에서 동작하는 것으로 메모리와는 전혀 다른 동작이다)
따라서 가용 가능한 메모리 공간이 불필요하게 남는 연속 할당의 단점을 보완할 수 있는 기법이 불연속 할당이며 내용이 많기 때문에 다음글에 이어서 작성하도록 하겠다.
'컴퓨터 공학 > 운영체제' 카테고리의 다른 글
메모리 관리 - Segmentation (0) | 2023.02.06 |
---|---|
메모리 관리 - Paging (0) | 2023.02.05 |
Dead Lock (교착 상태) (0) | 2023.01.27 |
프로세스 동기화 문제 (1) | 2023.01.27 |
프로세스 동기화 (0) | 2023.01.25 |