Game Tech Blog

7장. 물리 메모리 관리 본문

20 ~ 21 Theory Study/OS (Operating System)

7장. 물리 메모리 관리

jonghow 2021. 5. 3. 07:42
반응형

메모리 관리의 복잡성

- 폰 노이만의 "모든 프로그램은 메인 메모리 위에 올라와야 사용할 수 있다" 이론안에서 메모리를 더 효율적으로 적재하고, 공간을 확보하는 것은 매우 복잡한 문제이다.

 

이러한 관리는 메모리 관리 시스템(Memory Management System, MMS) 이 담당한다.

 

메모리 관리의 이중성

- 메모리 관리의 이중성은 쉽게말해, "서로다른 입장에서의 입장차이" 라고 판단된다.

프로세스 관점에선 더욱 많은 메모리를 독차지하려하고, 메모리 관리자 입장에서는 보다 더 효율적인 관리를 하고 싶어 하기 때문이다.

 

물론, 현재 메모리 관리 시스템은 각 요구사항을 적당히 타협봐서 완벽히 처리되었다고 한다. 

 

Compiler Vs InterPreter

구분 Compiler InterPreter
변수 선언 필요 선언 불필요
실행 컴파일 이후 실행 한줄씩 실행
장점 오류 찾기, 코드 최적화,
분할 컴파일에 의한 공동작업
실행 편리
사용 프로그램 C/C++, C#, Java 등등 대형 프로그램 Java Script, Basic 등등 간단한 프로그램

 

- 보통 간단한 웹이나, 일반 프로그램은 "InterPreter" 를 사용하고 게임, 앱 등등 대형 프로그램은 "Complier" 를 사용한다고 한다. 

 

메모리 관리자?

- 메모리 관리를 담당하는 하드웨어 (Memory Manage Unit, MMU) 

주로 가져오기, 배치, 재배치를 수행한다.

 

- 가져오기 : 프로세스, 데이터를 하드디스크에서 RAM으로 올리는 작업 

                한번에 메모리로 올리는 경우도 있고 스트림으로 읽어오는 방법도 있음

 

- 배치 : 메모리를 어떻게 배치하는가, 한번에 배치할 것인가, 나눠서 배치할 것인가 등을 결정한다.

 

- 재 배치 : 새롭게 실행된 프로세스를 가져오기 위해선 메모리 공간이 있어야하는데 꽉 찬경우 메모리에 있는 프로세스를 하드디스크로 옮기던지, 공간을 창출해야한다. 

이를 위해 오래된 프로세스를 내보내는 작업을 의미한다.

 

- 가져오기 정책 : 프로세스가 필요로하는 데이터를 언제 메모리로 가져올지 결정, 요청 시 가져오는 방법이 일반적이고 요청전에 미리 캐시처럼 가져오는 방법도 있다.

 

- 배치 정책 : 크기가 큰 프로세스를 어떻게 잘라서 배치할 것인가에 대한 정책, 각 크기를 같게 자르는 "페이징" 과 각 크기를 다르게 자르는 "세그먼테이션" 정책이 존재한다.

 

- 재배치 정책 : 메모리에 공간이 없을때 어떤 프로세스를 내보낼지 결정하는 정책, 자주 사용하지 않을 프로세스를 내보내는 것이 효율성이 좋겠지만, 자주 사용하는 프로세스는 가져오기, 배치등을 계속 수행해야하므로 비효율 적이다. 

이를 효율적으로 사용하지 않을 프로세스를 찾아서 내보내는 알고리즘을 "교체 알고리즘" 이라고 한다. 

이를 이용해 공간을 창출한다.

 

절대 주소 , 상대 주소 

구분 절대 주소 상대 주소
관점 메모리 관리자 입장 사용자 프로세스 입장
주소 시작 물리 주소 0번지 시작 물리주소 관계 없음, 항상 0번지 시작
주소 공간 물리 주소(실제 주소)공간 논리 주소 공간

- 상대 주소는 사용자 관점이다. 사용자 관점으로 모든 프로세스는 각각 0번지 부터 시작한다고 생각하면 된다.

모두 0번지 일수는 당연히 없고, 이를 알맞은 주소로 변경하여 절대적 물리주소를 접근하기 위해선 "재배치 레지스터" 가 필요하다.

 

Ex) 프로세스 요청(프로세스 물리주소 : 800) -> CPU 상대주소(80) -> 재배치 레지스터(720) -> 물리주소 접근(800)

 

과 같은 형식으로 이루어 진다.

 

단일 프로그래밍 환경에서의 메모리 할당

 

- 메모리 오버레이 : (프로그램의 크기 > 실제 물리 메모리의 크기)일 경우, 적당한 크기로 잘라서 인스턴스 시키는 기법을 말한다. 

 

예를 들어, 이렇게 사용할 수 있다. 

 

[ 이미지1. 메모리 오버레이, 모듈화 그룹 ]

공통적으로 필수적인 기능이나 데이터 등은 공통모듈 영역에 포함시켜 프로그램 실행과 동시에 메모리에 인스턴스화를 시키고, 나머지 빈 공간에는 특정한 키를 활성화 했거나, 다른 기능이 필요한 작업을 할 때 필요한 영역을 모듈화해서 해당하는 영역의 모듈만 인스턴스하는 것이다. 

 

이렇게 프로그램을 짜게되면 실행하면서 메모리를 올리는 크기가 현저히 줄어들며 메모리가 프로그램보다 작을 때도 실행이 가능하게 된다. 

그리고 모듈화의 장점인 약한 의존도(디커플링)가 두드러지며 해당 모듈이 없다고해도 프로그램이 종료되어버리는 불상사를 예방할 수 있다고 생각한다.

 

(물론 한번에 올리는 것보단 속도가 느리겠지만 메모리가 작은 컴퓨터에서의 사용성 까지 고려하면 좋은 방법이라고 생각한다.)

 

- 스왑 : 메모리 오버레이를 사용하면 모듈A, 모듈B 등으로 나눠서 사용할 수 있고, 물리메모리(RAM) 보다 큰 프로그램을 실행할 수 있다. 다만 모듈A를 사용하고 모듈B를 사용할 때 모듈A는 어디에 놓으면 좋겠는가..? 

 

언제 사용할 지도모르고, 다 사용 안했을지도 모르는데 말이다. 이럴때 저장장치(하드디스크)의 별도 공간에 보관한다고 한다. 이 영역을 "스왑영역" 이라고 한다. 

 

스왑 영역은 다음과 같이 구성되어 있다.

 

[ 이미지2. 스왑 영역의 구성 ]

위 이미지를 참고하면 알다싶이, 디스크는 스왑영역이라는 장소만 빌려주고, 관리자는 메모리 관리자가 관리한다.

 

(여기서 의문점이 있는데, 모듈A와 모듈B가 둘 다 존재할 수 있으면 스왑영역을 사용하지 않아도 되지 않나싶다.

자료를 더 찾아봐야 알겠지만 지금은 모듈A가 있고 모듈B를 불러왔을 때, 물리메모리 자리가 없다는 것을 가정하고 이야기를 한것이 아닐까 싶긴하다..)

 

다중 프로그래밍 환경에서의 메모리 할당

한번에 여러 프로세스가 실행 될 경우의 메모리 문제를 이야기 할 것이다.

 

1) 메모리 분할 방식

- 가변 분할 방식 : 프로세스의 크기에 따라 메모리를 분할한다. ( 세그먼테이션? )

- 고정 분할 방식 : 프로세스를 동일한 크기로 메모리를 분할한다. ( 페이징? )

 

각 분할 방식을 이미지로 이야기하면 다음과 같다.

 

[ 이미지3. 두 개의 프로세스가 동시에 실행되는 경우 ]

가변 분할 방식은 A,B 프로세스의 크기대로 메모리를 할당해서 구해주는 반면, 고정 분할 방식은 프로세스를 각각 잘라서 넣어준다는 특성이 있다. 

이러한 특성은 각각 장단점이 존재한다.

 

구분 가변 분할 방식  고정 분할 방식
장점 프로세스를 한번에 연속된 공간에 배치 메모리 관리가 수월함
메모리가 일정 크기로 나눠져 있기때문에 프로세스를 옮기는 메모리통합 과정의 불필요
단점 - 메모리 관리의 복잡성
- 외부 단편화로 인해 사용중인 프로세스의 자리를 옮기는 과정이 필요함
- 정해진 페이징 공간 단위를 무조건 할당해야하므로, 내부 단편화 발생

이러한 장점들이 두드러지게 발견되기때문에 각 장점을 혼합하여 사용한다.

 

( 생각해보면 고정 분할 방식은 우리가 일상생활에서 식당을 예로 들 수 있을 것 같다. 다만, 가변 분할 방식은 글쎄...)

 

가변 분할 방식의 메모리 관리

- 메모리 배치 방식 : 1) 최초 배치 2) 최적 배치 3) 최악 배치 etc.. 버디 시스템 등등..

 

1) 최초 배치 : 외부 단편화를 고려하지 않는다. 프로세스가 들어갈 수 있는 가장 가까운 물리메모리 공간을 찾아서 점유한다.

 

2) 최적 배치 : 메모리의 빈 공간을 모두 확인한 후 들어갈 수 있는 크기 가운데 가장 작은(단편화가 덜 발생할) 공간을 프로세스가 점유한다.

 

3) 최악 배치 : 빈 공간을 모두 확인한 후 가장 큰 공간에 프로세스를 배치한다. (최적 배치와 반대 개념)

 

4) 버디 시스템 : 아래 서술되어 있음

 

- 조각 모음 : 가변 분할 방식에선 최적 배치에서 (메모리 크기 == 프로세스의 크기) 인 경우를 제외하면, 모두 외부 단편화가 발생한다.

 

한 프로세스가 종료되었을때, 단편화 되는 공간을 최소화하기 위해 자리를 땡겨앉는 작업이 필요한데, 이것을 조각 모음이라고 한다.

 

조각모음의 처리 순서는 다음과 같다.

1. 이동할 프로세스의 동작을 멈춘다.

2. 프로세스를 적당한 위치로 변경한다. 주소가 바뀌기 때문에 상대 주소 값을 변경한다.

3. 다시 시작한다.

 

고정 분할 방식의 메모리 관리

고정 분할 방식의 고질적인 문제점은 내부 단편화 이다. 

가변 분할 방식은 조각모음으로 해결 할 수 있지만, 내부단편화는 조각 모음이 불가능하고 다른 프로세스에 배정할 수도 없다.

 

버디 시스템

기본적으로 "가변 분할 방식"인 버디시스템은 외부단편화를 완화할 수 있으며, 고정 분할 방식과 유사점이 존재한다.

 

작동방식은 다음과 같다.

1. 프로세스의 크기에 맞게 1/2로 분할한 후 프로세스를 메모리에 배치

2. 나뉜 메모리의 각 구역에는 프로세스가 1개만 점유

3. 프로세스가 종료되면 주변의 빈 조각과 합친다.

 

프로세스간의 거리를 최소화하고 비슷한 크기의 프로세스들이 모여있기 때문에 통합하기가 수월하다.

공간 관리의 효율성 측면에서 고정 분할 방식과 버디 시스템은 비슷한 수준이기 때문에 보통 고정 분할방식이 많이 사용된다고 한다.

 

 

 

 

 

 

 

 

 

 

 

반응형
Comments