메모리 관리(물리 메모리, 가상 메모리)

Kyung yup Lee·2021년 2월 22일
5

운영체제

목록 보기
5/5

개문

우리는 흔히들 램이 몇 기가냐고 얘기하고는 한다. 8기가, 16기가 등 다양한 크기의 램이 달려있는 컴퓨터를 사용한다.

컴퓨터를 조금 공부해봤던 사람이라면 프로그램이 메모리에 올라가서 작동되기 시작하는 것을 알고 있을 것이다.

그러면 프로그램의 크기는 기가바이트 단위인데 어떻게 여러개의 프로그램을 동시에 돌릴 수 있을까. 그 크기의 합은 램의 크기를 훌쩍 뛰어넘는데 말이다.

가상메모리

가상메모리의 의미

여기서 시작하는 것이 가상메모리의 개념이다. 부족한 물리메모리를 가상메모리를 만들어 사용하는 것이다. 가상메모리라는 것은 단어 그대로의 virtual이 아니다. 마치 없는것을 만들어내는 듯한 느낌인데, 실제로는 이미 있는 것을 다르게 사용하는 의미이다. 여기서 가상메모리의 실제 공간은 하드디스크 + RAM이 된다.

물론 실제로 프로세스가 실행될 수 있는 메모리 공간은 램 크기 만큼이지만 운영체제가 가상메모리 공간을 프로세스에게 제공해줌으로써 프로세스는 자신을 모두 메모리에 적재했다는 착각을 한다. 프로세스 입장에서는 가상메모리 공간도 물리메모리 공간으로 인식하는 것이다. 그리고 운영체제는 가상메모리에 걸쳐서 적재된 프로세스의 부분이 실제로 적재가 필요하다면 물리메모리 공간과 swap(변경) 해준다. 프로세스의 모든 코드가 한번에 물리메모리에서 돌아가는 일은 없다. 필요한 부분만 실제 물리 메모리로 올라가기만 하면 되기 때문에, 이 부분을 운영체제가 계속 swapping 해주는 것을 통해 가상메모리를 구현한다.

논리주소(물리 주소로 변환)

메모리에는 고유의 주소값이 있다. 이를 물리 주소라고 부른다. 가상메모리는 하드디스크 공간을 이용해 마치 물리메모리가 훨씬 커진 것처럼 사용한다고 했다. 그러면 그 커진 메모리에도 주소가 붙어야 하는데, 물리메모리가 아니기 때문에 물리 주소가 붙을 수 없다. 이를 위해 붙이는 주소가 논리 주소이다. 물리 메모리에는 일반 프로세스 뿐만 아니라 운영체제도 적재되어 사용되고 있다. 이 운영체제가 사용중인 메모리는 직접 접근하면 안되는 메모리 공간이다. 때문에 운영체제 부분의 다음 주소부터 논리주소 0번으로 시작한다. 그리고 가상메모리까지 모든 주소를 붙이게 되는 것이다.

그렇다면 논리주소만으로 메모리 접근이 가능한가? 실제로 데이터 처리를 하기 위해서는 메모리에 주소를 통해 접근해야 한다. 논리주소 만으로는 메모리에 접근할 수 없다. 때문에 이 논리주소를 물리주소로 변환시켜주는 과정이 필요하다.

예를 들어 현재 하드디스크 공간(가상메모리) 부분에서 적재되었다고 판단되는 프로세스 데이터가 실제로 물리메모리에 올라와야될 경우(실행 되어야 할 경우) 논리주소를 물리주소에 연결한다. 이를 매핑이라고 한다. 이 매핑을 관리하는 것이 메모리 관리자의 역할이다.

메모리 관리자

위에서 프로세스를 필요한 부분만 물리메모리에 올린다고 서술했다. 그러면 당연히 프로세스를 어떻게 쪼갤것인지, 물리메모리에는 어떻게 적재할 것인지, 만약 물리메모리가 꽉 차면 어떻게 하는지 궁금해야 한다.
이 부분들을 담당해주는 것이 메모리 관리자이다. 메모리 관리자는 대표적으로 세 가지 일을 한다.

가져오기(fetch)

프로세스가 필요로 하는 데이터를 언제 메모리로 가져올지 결정하는 정책이다. 프로세스가 해당 코드 데이터가 필요할 경우 불러오는 것이 일반적이지만, 조금 더 빠르게 이 데이터를 받아오기 위해 캐싱을 사용한다.

배치

가져온 프로세스 조각을 메모리의 어떤 곳에 위치 시킬지 결정하는 정책이다. 프로세스 조각의 크기는 천차만별일 것이다. 메모리를 일정한 크기를 잘라놓고 그 크기에 프로세스를 맞게 자르는 기법을 페이징(paging) 이라고 하고, 프로세스를 자르고 거기에 메모리 크기를 맞추는것을 세그먼테이션(segmentation) 이라고 한다.

재배치

메모리가 꽉 찼을 때 어떤 프로세스를 내보낼지 결정한다. 사용하지 않을 프로세스만 내보내면 가장 효율적이겠지만 그런 프로세스를 찾기 힘들고 가장 가깝게 효율적인 알고리즘을 도입하도록 해야한다.

메모리 분할 방식(배치)

메모리 분할 방식은 효율성을 추구하기 위한 운영체제의 끝 없는 싸움이다. 페이징과 세그먼테이션 두 방식 모두가 장단점이 존재한다. 두 가지 방식을 적절히 섞어야 효율적인 메모리 운용이 가능하다.

프로세스에서 요청을 받았다 하자(얼마나 효율적으로 받아올지는 조금 있다가 생각하자)

페이징

먼저 페이징 부터 시작하자면, 페이징은 가상메모리를 일정 크기로 쪼개서 그 크기에 맞춰 프로세스를 잘라 넣는 방식이다.
위에서 논리주소에 대한 설명을 했는데, 가상메모리를 물리메모리에서 사용하기 위해서는 반드시 주소변환이 필요하다고 했다. 페이징은 가상메모리를 쪼개서 페이지로 만들고 물리메모리도 페이지와 같은 크기로 쪼개서 "프레임" 으로 만든다. 그리고 해당 페이지와 프레임을 매핑한 페이지 테이블을 만든다. 이 페이지 테이블에는 인덱스(페이지 번호)가 붙은 공간에 프레임 번호가 들어가있다. 그리고 페이지는 반드시 프레임보다 개수가 많을 수 밖에 없기 때문에 invalid 값이 들어가 값이 들어가있는 경우가 있다. 이 경우에는 해당 페이지가 스왑영역(하드디스크 부분) 에 존재한다는 이야기이다.

페이징의 장점은 메모리 조각의 사이즈가 모두 같기 때문에 해당 메모리를 차곡차곡 쌓고 만약 이 메모리가 해제된다고 하더라도, 바로 다른 데이터를 그 자리에 바로 집어 넣을 수 있다. 모두 다 같은 크기이니깐.

하지만 프로세스 크기가 작더라도 같은 메모리 사이즈로 쪼개야하기 때문에 해당 블록에 메모리가 남을 수 있다. 이것을 내부단편화라고 한다. 이런 현상이 심해지면 메모리 낭비가 심해질 것이다.

세그먼테이션

페이징 기법이 물리메모리와 가상메모리 공간을 같은 크기로 쪼개서 프로세스를 끼워넣는 방식이었다면 세그먼테이션은 프로세스 크기에 맞춰 물리메모리와 가상메모리를 쪼개는 방식이다. 물리메모리에는 프로세스 크기에 맞춰 세그먼트가 배치되게 된다. 세그먼테이션 기법에서는 같은 단위 크기의 메모리를 사용하지 않기 때문에 반드시 시작 메모리 주소가 매핑 테이블에 포함되어야 한다. 페이징의 경우 모든 페이지의 크기가 같았기 때문에 따로 기록할 필요가 없었다.

세그먼테이션의 장점은 내부 단편화가 전혀 생기지 않고 페이지 테이블이 단순하다는 것이지만, 물리 메모리의 메모리 구조가 복잡해진다는 단점이 있다. 왜냐하면 프로세스 크기에 맞춰 물리 메모리에 계속 적재되고 삭제하는 것이 반복되면서 큰 프로세스는 메모리 사이에 들어가지 못하기 때문이다. 이를 외부 단편화라 하는데 프로세스 처리가 반복되면 물리 메모리에 구멍이 계속 나게 된다.

혼용 기법

세그먼테이션과 페이징 기법을 혼용하는 것은 프로세스를 세그먼트 단위로 쪼개고 이것을 다시 페이지 단위로 쪼개는 것을 의미한다.

이 방식의 장점은 프로세스를 바로 페이징해버리면 프로세스의 코드, 스택, 힙, 데이터 영역 등이 실제 논리관계랑 상관없이 물리크기로 잘려버리기 때문에 코드의 안정성이 떨어진다는 단점을 해결할 수 있다는 것이다. 세그먼테이션을 통해 논리적으로 합당한 사이즈로 프로세스를 쪼개고, 이것을 다시 페이징을 한다. 세그먼테이션 전체를 세그먼테이션 테이블에 매핑한다. 세그먼테이션 테이블에는 가상 메모리의 시작 주소가 들어가고 이 테이블 한 섹션이 다시 페이지 테이블로 매핑된다. 그리고 각 페이지 테이블은 물리메모리로 매핑되는 것을 통해 가상메모리를 구현한다.

실제 OS에서는 이 기법을 많이 사용한다. 세그먼테이션, 페이징의 단점을 모두 어느정도 커버할 수 있기 때문이다.

재배치(요구 페이징)

이전 내용에서 프로세스는 모두 메모리로 올라와 사용되지 않는다고 했다. 특정 부분만 올라와서 메모리에 적재되게 되는데, 프로세스가 작동하면서 특정 모듈이 필요하게 될 경우, 메모리에 해당 모듈을 요청하는 것을 요구 페이징이라고 한다.

요구 페이징이 발생했을 때, 메모리에 해당 모듈이 적재되어있지 않은 경우, 즉 스왑 영역에 해당 모듈이 있는 경우를 페이지 폴트(page fault) 라고 한다.

페이지 폴트가 발생할 경우 스왑영역에서 메모리 영역으로 불러와야 하는데, 이런 페이지 폴트가빈번하게 발생할 경우, 해당 로딩 시간 때문에 사용자에게 큰 불편을 주게 된다. 그렇기 때문에, 메모리에서 사용될 가능성이 높은 프로세스 모듈을 미리 스케쥴링해서 메모리에 적재해 주는 방법을 고안하는 것이 필요하다.

위의 스케쥴링의 중요한 기준이 되는 것이 지역성이다. 지역성에는 공간의 지역성과 시간의 지역성이 대표적으로 있는데, 공간의 지역성은 현재 접근했던 데이터에서 가까운 위치의 데이터에 접근할 확률이 높다는 것이고, 시간적 지역성은 가까운 시간대에 접근했던 데이터가 더 먼 시간에 접근했던 데이터 보다 접근할 확률이 더 높다는 것이다.

해당 기준을 가지고 알고리즘을 페이지 교체 알고리즘을 짜게 된다.

profile
성장하는 개발자

1개의 댓글

comment-user-thumbnail
2021년 7월 28일

너무 유익하네요 ~ ^^ 정보 감사합니다~

답글 달기