IT_etc/유용한 전산 지식들..

[펌][OS]가상 메모리(Virtual Memory)

JJun ™ 2015. 1. 30. 20:27



 출처

 : http://mooneegee.blogspot.kr/2015/01/os-virtual-memory-1.html

 : http://mooneegee.blogspot.kr/2015/01/osvirtual-memory-2-virtual-address.html

 : http://mooneegee.blogspot.kr/2015/01/os-virtual-memory-3-page-page-frame.html



1. 시스템과 메모리 할당 사이의 관계


 가상 메모리가 등장했다. 윈도우를 사용하다보면 어쩌다가 한 번쯤은 만나볼만한 녀석이다.
나는 종종 가상 메모리를 늘려달라는 잔소리를 Windows7으로부터 들은 경험이 있다.



  Google에서 검색해보면 가상 메모리의 크기를 조절하여 Windows7을 최적화할 수 있다는 글도 보인다.
이래나 저래나 가상메모리가 중요한 녀석일 것 같다는 생각은 가질만하다.


32비트 시스템과 프로세스 메모리 할당

 처음부터 '이거 뭐야?'하는 내용이 등장한다. 32비트 시스템에서 프로세스 생성 시 4G바이트의 메모리를 할당받을 수 있다고 한다.
시작부터 황당하기 그지 없다. 내가 전에 사용했던 컴퓨터는 32비트 시스템이고, 돈 좀 써서 2G바이트 RAM를 장착했었다.
그 당시에 상당히 좋은 사양이었고, 게임도 아주 잘 돌아갔다. 그런데 이상한 점은 32비트 시스템에서 프로세스 생성 시 4G바이트의 메모리를 할당받을 수 있다는 사실이다. 나는 분명 2G바이트 크기의 RAM을 가지고 있었다. '모자라는 상태에서 어떻게 메모리를
할당했지?', '뭐하러 4G바이트나 되는 크기를 할당하지? 윈도우 계산기 켜는데 4G를 할당한다고?' 등등의 의문이 생길 수 밖에 없다. 

 이런 의문들을 하나씩 해결해보자. 먼저 32비트 시스템에서 프로세스 생성 시 최대 4G바이트의 메모리를 할당받을 수 있다는데 왜 그런가? 32비트 시스템은 또 무슨 말인가? 이것에 대한 답을 찾기위해서는 시스템 버스(system bus)라는 것에 대해서 간단히 언급할 필요가 있다. 시스템 버스는 컴퓨터에서 데이터를 이곳에서 저곳으로 옮기는 통로와 이를 관리하는 장치들이라고 생각하자. 이 시스템 버스에서 데이터가 이동하는 실질적인 통로 역할을 하는 것이 바로 I/O 버스이다. 이 I/O 버스가 한번에 전달할 수 있는 데이터의 크기가 바로 32비트이다. 이것 말고도 32비트 시스템에서 32비트가 의미하는 것은 바로 CPU와 같은 장치가 한번에 처리할 수 있는 데이터의 크기이다. 정리하면 한번에 I/O 버스로 이동시킬 수 있는 데이터의 크기도 32비트이고, CPU가 처리할 수 있는 데이터의 크기도 32비트이다. 이 둘의 크기가 같은 것은 우연이 아니다. 한번에 32비트를 처리할 수 있는데, 16비트를 전달해주는 것도 웃긴 일이고 64비트를 전달해주는 것은 무리이다.


 위 그림에서 address bus, control bus, data bus라고 표시된 것들이 바로 시스템 버스에 속하는 녀석들이다. 각 장치들을 연결하면서 데이터 전달 통로 역할을 한다는 사실에 집중하자. 그리고 3가지 bus들의 역할은 각각 다르지만 여기서는 넘어가도록 하겠다.

 그런데 프로세스와 쓰레드를 포스팅할 때도 그랬지만 프로그래머에게 가장 중요한 것 중 하나가 메모리 아니던가. 프로그래머는 메모리를 생각하지 않을 수 없다. 32비트 시스템을 생각할 때도 메모리 측면에서 접근해보자. 

 또 어이없는 상황을 가정해보자. 나는 8비트 시스템에 100G 바이트 RAM를 소유하고 있다. 100G바이트라니 엄청 신나는 일이다. 과연 신나는 일인지 생각해보자. 먼저 8비트 시스템에서는 메모리 주소 공간을 표현할 수 있는 범위는 2^8 만큼이다. 왜 2^8인가? 주소값을 표현하는데 8비트 이상 사용할 수 없기 때문이다.(주소값도 데이터 중 하나이다) 8비트 시스템이 한번에 처리할 수 있는 비트 수는 8개이고, 이에 따라 한번에 다룰 수 있는 주소값은 2^8만큼을 표현할 수 있다. 결국 2^8 = 256, 즉 0 ~ 255까지만 주소를 표현할 수 있다. 100G 바이트 RAM을 달아놓으면 뭐하나? 결국 쓸 수 있는 메모리 공간의 크기는 고작 256바이트 만큼이다. 1/4G 바이트 밖에 사용하지 못하였다.

 그러면 32비트 시스템의 경우는 어떠할까? 한번에 처리할 수 있는 데이터의 크기가 32비트이고, 주소값을 표현하는데 32비트를 모두 사용한다면 최대로 표현할 수 있는 메모리 공간의 크기는 2^32가 된다. 딱 봐도 커보이는 숫자이다. 이를 Windows에 있는 전지전능한 calc.exe를 실행시켜 계산해보면 4294967296이라는 숫자가 나온다. 이 숫자가 바로 4G 바이트를 의미하는 숫자이다. 32비트 시스템에서는 프로세스는 최대 4G 바이트를 할당받을 수 있다는 이유가 이제 설명되었으리라 믿는다.

 최근에는 64비트 시스템이 일반화되고 있다. 그럼 64비트 시스템의 경우 프로세스 당 최대 얼마만큼의 메모리를 할당할 수 있는가? calc.exe의 도움을 받아서 계산해보자. 무려 18446744073709551616라는 숫자가 계산된다. 그냥봐도 큰 수이다. 매우 크다. 여튼 중요한 사실은 한 번에 처리할 수 있는 데이터의 단위가 곧 몇 비트 시스템인지를 결정하고, 이는 곧 메모리를 나타내는 주소값을 표현하는데도 연결되는 사항이라는 사실이다.


아직도 해결되지 못한 궁금증

 시스템과 메모리 할당 사이의 관계는 이해했다. 그렇다면 이제 처음으로 돌아가서 32비트 시스템에서 2G 바이트 RAM에 어떻게 4G 바이트 메모리를 할당할 수 있는지 따져보자. 뜬금없지만 포스트이 길어졌으므로 다음 포스팅으로 넘겨야겠다.    





2. 가상 주소 시스템(Virtual Address System)


 시스템과 메모리 할당 사이의 관계에서 해결하지 못했던 궁금증을 이번에는 반드시 개운하게 풀어보고자 한다. 하지만 포스팅하면서도 또 분량이 늘어져서 3편, 4편으로 이어질 것 같다. 분명히.


가상주소(virtual address)

 지난 포스팅에서 32비트 시스템에서 2G바이트 RAM으로 어떻게 4G바이트를 할당할 수 있는지 답을 내리지 못하고 마무리하였다. 분명한 사실은 4G바이트를 할당하였다는 점이다. 어떻게든 할당하였다. 메모리가 모자람에도 불구하고 할당하였다는 점은 실재 메모리말고 다른 어떤 메모리가 있다는 것을 의미한다. 그래야 실재 메모리 이상을 할당할 것이 아닌가. 그런 메모리를 할당하고 관리하는 주체가 바로 운영체제이다.


 먼저 32비트 시스템으로 돌아가보자. 프로세스를 하나 실행하여 메모리를 할당받는다. 최대로 할당받을 수 있는 크기는 물리적인 메모리 크기인 2G 바이트와 별개로 시스템이 표현할 수 있는 최대의 메모리 주소 공간의 크기였다. 즉 4G바이트만큼 할당받을 수 있었다. 물리적 메모리를 초과하는 용량은 4G바이트를 도대체 어디서 할당한다는 말인가? 이것 의문을 먼저 해결해보자.

 메모리 계층 구조를 떠올려보자. 느린 대신 값싸고 용량이 엄청 큰 하드디스크는 요즘 1T바이트짜리도 많이 사용한다. 그리고 메모리 계층 구조에서 알 수 있듯이 하드디스크라고 해서 메인 메모리 같은 역할을 수행하지 말라는 법은 없다. 느려서 문제일 뿐이다. 속도가 느리다는 문제를 극복할 수 있는 대안이 나온다면 하드디스크의 빵빵한 용량을 메모리 할당에 활용할 수는 있을 것 같다는 생각이 든다. 그리고 추가로 4G바이트만큼을 늘 할당할 필요도 없을 것 같다. 한번에 4G바이트만큼이나 차지하는 프로세스는 흔치 않다.


출처는 내 컴퓨터^^


 자극적인 빨간 색 네모 영역이 바로 사용하는 메모리를 표시하고 있다. Chrome이 매우 열심히 일을 하고 있다. 가장 큰 메모리를 Chrome 중 하나가 약 90,000K바이트이다. 90M바이트이다. 4G바이트로 할당하는 것은 비효율의 극치라고 볼 수 있다. 그러니 적당한 크기로 할당하는 것이 좋겠다는 생각이 든다. 실재로 운영체제도 프로세스 당 4G바이트씩 할당하는 짓은 하지 않는다. 이론적으로 그렇다는 말이다.

 지금까지의 내용을 정리해보자. RAM과 같은 메모리의 물리적 크기의 제한은 있지만 이를 초과하는 메모리 할당을 하드디스크로 할 수 있을 것 같다. 그리고 하드디스크를 사용하는 만큼 속도 문제를 고려해야할 것 같다.

 그럼 드디어 가상주소를 알아보자. 32비트 시스템에서 프로세스에 할당할 수 있는 최대 크기인 4G바이트 메모리 공간은 RAM가 같은 메모리의 물리적 주소가 아니라 실제로 존재하지 않은 가상의 주소이다. 그리고 가상의 주소를 사용하여 할당한 4G바이트에 해당하는 공간을 가상 메모리 공간(virtual address space)라고 한다.

 결국 32비트 시스템에서 할당할 수 있는 4G바이트 크기 메모리 공간은 하드디스크를 이용한 가상의 메모리 공간이었고,
이런 가상의 공간에 대한 지정해주기 위해서 가상 주소 시스템이 필요하다. 

 이제 가상 주소 공간이 어떻게 하드디스크에 구성이 되는지, 그리고 실제 RAM과는 어떤 관계가 있는지 살펴보면 된다.







3. 페이지(Page), 페이지 프레임(Page Frame), 페이지 테이블(Page Table)


 시스템과 메모리 할당 간의 관계와 가상 주소 시스템까지 알아보았다.
 이제 아직 해결하지 못한 두 문제를 해결하고자 한다. 이 문제를 해결하면 가상 메모리에 대한 핵심을 거의 이해했다고 봐도 무방하다.


아직 해결하지 못한 문제들 

 1. 32비트 시스템에서 하드디스크를 이용하여 프로세스마다 가상 메모리 공간 4G바이트를 할당하는 것은 효율적이지 못하다.

 2. 하드디스크는 메인 메모리와 비교했을 때 느리다.

 이 두 가지 문제를 해결하기 위해서 페이지, 페이지 프레임, 페이지 테이블이 필요하다.


페이지, 페이지 프레임, 페이지 테이블

 먼저 1번 문제를 해결해보자.

 불필요하게 많은 공간을 하드디스크에 할당하는 것은 올바르지 못하다. 4G바이트나 되는 공간을 할당하면 낭비도 심하고 시간도 오래 걸리기 때문이다. 그래서 좀더 작은 단위로 할당하는 것은 어떤가?



 위의 그림을 살펴보자. 32비트 시스템에서 표현할 수 있는 메모리 주소의 범위는 4G만큼이다. 이를 사용하여 가상 주소를 표시한다. 그림 좌측의 긴 막대가 바로 가상 주소 공간이다. 이는 논리적인 주소일뿐 물리적인 메모리 주소가 아니다. 그래서 가상 주소 공간의 크기는 4G만큼이지만 실제 메인 메모리의 크기와 차이가 발생한다. 여튼 그림에서 가상 주소 공간의 크기는 64K이다. 64K라면 16비트 시스템이라고 유추할 수 있다. 그림에서 64K의 공간을 16개로 분할하였다. 왜 분할하였겠는가? 한 번에 4G바이트씩 할당하는 것은 비효율적이기 때문이다. 그래서 4K바이트로 할당 용량을 줄여서 낭비되는 공간을 줄였다. 1번 문제점의 해결책이 바로 이 방법이다. 이렇게 4K로 나눈 가상 주고 공간의 블록을 페이지(page)라고 부른다.

  이제 그림의 오른쪽 짧은 막대를 보자. 물리적인 메모리 주소라고 표시되어 있다. 이것이 메인 메모리의 실제 주소 공간이다. 메인 메모리의 주소 공간 역시 4K바이트 단위로 나눠져 있다. 가상 주소 공간과 크기를 맞추었기 때문이다. 메인 메모리의 블럭을 페이지 프레임(page frame)이라고 부른다.

 그럼 가상 주소 공간과 물리 주소 공간을 맵핑(mapping)시키기만 하면 된다. 가상 주소 공간에 숫자는 물리 주소 공간의 어디에 맵핑되는지를 나타낸다. 예를 들어 0 ~ 4K 구간은 물리 주소 공간의 8 ~ 12K 구간에 맵핑되어 있다. 이렇게 맵핑을 하면 무엇이 좋은가?
이는 2번 문제점에 대한 답이 된다. 가상 주소 공간을 활용하면 물리 주소 공간에 비해서 표현할 수 있는 메모리 주소의 범위가
증가하고, 더 많은 메모리를 사용하는 효과를 얻을 수 있다. 다만 하드디스크는 느리다는 단점이 있다.
느린 하드디스크의 한계를 극복하고자 하드디스크와 맵핑된 메인 메모리를 활용한다. 이는 메모리 계층 구조와 동일한 원리이다. 


 가상 주소 공간과 물리 주소 공간을 맵핑한 정보는 페이지 테이블(page table)을 통해 관리된다.
위의 그림이 바로 페이지 테이블에 대한 설명이다.

 만약 가상 주소 공간 전체에 페이지가 할당되어 있는 경우를 생각해보자. 메인 메모리는 가상 주소 공간의 페이지 전체를 담을 수
없다. 그럼 가상 주소 공간의 일부분만 메인 메모리에 올려서 사용할 수 밖에 없을 것이다. 그런데 필요한 데이터가 메인 메모리의 존재하지 않으면 어떻게 하나? 이는 캐쉬 알고리즘을 이해하고 있다면 쉽게 알 수 있다. 가상 주소 공간에 존재하는 즉 실제로는 하드디스크에 저장된 데이터를 메인 메모리로 올리고, 가장 불필요하다고 판단되는 데이터를 다시 하드디스크로 내리면 된다. 이 과정에 대해서 조금더 부연 설명을 하면 올리고 내리는 데이터는 스왑파일(swap file)이라는 형태로 저장된다. 내리고자 하는 데이터를 스왑파일로
저장하여 하드디스크로 저장하고, 올리고자 하는 데이터 또한 스왑파일로 저장된 상태이므로 메인 메모리로 바로 올리면 된다. 


정리하면

 시스템이 표현할 수 있는 주소 범위를 활용하여 가상 주소 공간으로 사용한다.
 가상 주소 공간은 하드디스크를 활용하여 데이터를 저장할 수 있다.
 프로세스를 실행하는데 필요한 데이터는 메인 메모리로, 불필요한 데이터는 하드디스크로 저장한다.
 가상 주소 공간을 관리하는 정보는 페이지 테이블에 보관되어 있다.
 가상 메모리는 메모리 계층 구조, 캐쉬의 장점을 활용한다.