Computer Science/Operating System

[운영체제] 가상 메모리의 이해

HJChung 2021. 2. 19. 01:52

가상 메모리(Virtual Memory)

리눅스의 각 프로세스마다 4GB를 차지한다. 그런데 통상 메모리는 16GB? 정도인 것도 있고, 코드는 메모리에 반드시 있어야 하는데 여러개의 프로세스들 실행할 때 메모리 크기의 한계를 어떻게 극복할 수 있을까?

즉 어떻게 하면 한정된 메모리에서 여러 프로세스를 실행시킬 수 있도록 메모리 구조를 가져갈 것인가? 

이때 활용하는 것이 가상 메모리이다. 

또한 가상 메모리를 통해 프로세스간 공간 분리로 프로세스 이슈가 전체 시스템에 영향을 주지 않을 수 있다

 

가상 메모리의 기본 아이디어는 프로세스는 가상 주소를 사용하고, 데이터를 사용(읽고/쓰기) 할 때 물리 주소로 변환해주면 된다는 것이다. 

즉, 가상 메모리 시스템을 사용하기 위해서는 가상 주소(virtual address)와 물리 주소(physical address)가 필요하다. 

  • virtual address(가상 주소): 프로세스가 참조하는 주소
  • physical address(물리 주소): 실제 메모리 주소

그리고 특정 가상 주소가 어느 물리 주소에 매핑되어있는지 알 수 있어야 한다. 이 때 필요한 것이 MMU이다. 

  • MMU(Memory Management Unit): CPU에 코드 실행시, 가상 주소 메모리 접근이 필요할 때, 해당 주소를 물리 주소 값으로 변환해주는 하드웨어 장치

즉, CPU는 가상 메모리를 다루고, 가상 메모리의 가상 주소에 접근시 MMU하드웨어를 통해 물리 주소로 변환되어 물리 메모리에 접근한다. 

페이징 시스템(paging system)

가상 메모리 시스템을 구현하는 다양한 방법 중 가장 많이 쓰이는 방법이 페이징 시스템이다.

  • paging: 크기가 동일한 page로 가상 주소 공간과 이에 매핑되는 물리 주소 공간을 관리하는 것이다. 
  • page(page frame): 고정된 동일한 크기의 block
  • paging table: 프로세스의 PCB에 Page Table 구조체를 가리키는 주소가 있는데 ,이 Page Table에는 물리 메모리에 있는 page frame 번호와 해당 페이지의 첫 물리 주소 정보를 매핑한 표이이다. 

예를 들어, 리눅스에서는 4KB로 paging을 하고, Page Table에 해당 정보를 기록/사용한다. 

 

  • p: 가상 메모리의 page 번호
  • d: p안에서 참조하는 위치 (페이지 내부 주소; 변위; offset)

paging system에서  해당 프로세스에서 특정 가상 주소를 가지고 어떤 데이터에 접근하고자 하면, 

→ page table에 해당 가상 주소와 그 page 번호(p)가 있는지 확인한다. 

→ page 번호가 있으면 이와 매핑된 물리 주소(p')를 알아낸다

→ 그러면 페이지 처음부터 얼마 떨어진 위치인지를 알려주는 변위(d)를 더하면 

→ p' + d 가 실제 물리 주소가 된다. 

1) 다중 단계 페이징 시스템

4GB의 프로세스를 모두 페이지로 나눈다면 이 중 당장 사용되지 않는 데이터까지 페이지로 만들어질 것이고 이러면 너무 많은 페이지로 나눠질 것이다. 이렇게 하지 말고 페이징 정보를 단계를 나누어 생성하면 필요없는 페이지는 생성하지 않고 공간 절약이 가능해진다. 

2) 페이징 시스템과 공유 메모리

어떤 경우에는 프로세스간 동일한 물리 주소를 가리키게 하여 공간 절약과 메모리 할당 시간을 절약 할 수도 있다. 

MMU와 TLB

MMU는 CPU에 코드 실행시, 가상 주소 메모리 접근이 필요할 때, 해당 주소를 물리 주소 값으로 변환해주는 하드웨어 장치이다. 그러면 매번 MMU가 물리 주소를 확인하기 위해 아래 그림과 같이 메모리를 갔다와야하는데 이 과정을 좀 더 효율적으로 할 순 없을까?

이 때 사용되는 것이 TLB이다. 

  • TLB(Translation Lookingside Buffer): 최근 물리 주소로 변환된 가상 주소 정보를 저장하여 페이지 정보를 캐쉬할 수 있는 하드웨어

Demand Paging

위와 같은 paging system을 사용하면 프로세스에서 나눠진 page를 언제 물리 메모리에 올려놓을지에 대한 정책이 필요하다. 선행 페이징으로 하면 그냥 프로세슬를 실행하자마다 page먼저 다 올려두는 것인데 이것 보다 실제로 필요할 때 page를 메모리에 올리는 것이 좋을 것이다. 이게 demand paging이다. 

  • Demand Paging: 프로세스의 모든 데이터를 메모리로 적재하지 않고, 실행 중 필요한 시점에서만 메모리로 적재함

이 때 valid/Invalid bit가 사용된다. 

  • Invalid: 사용되지 않는 주소 영역인 경우, 페이지가 물리적 메모리에 없는 경우 (valid는 반대)

처음에는 모든 page가 invalid로 초기화되고, 사용되면 valid로 되는데, address translation시에 invalid bit이라면 page fault가 발생한다.

  • page fault:  어떤 페이지가 물리 메모리에 없을 때 발생하는 인터럽트로, page fault가 발생하면 운영체제가 해당 페이지를 물리 메모리에 올려준다. 

 

여기까지의 과정을 앞선 MMU와 TLB에 더해서 도표로 보면, 이러한 과정으로 진행된다. 

페이지 교체 정책(Page replacement policy) 

운영체제가 특정 페이지를 물리 메모리에 올리려고 하는데 물리 메모리가 다 차있다면? 기존 페이지 중 하나르 물리 메모리에서 저장 매체로 내리고(저장) 새로운 페이지를 해당 물리 메모리 공간에 올려야한다. 이 때 어떤 페이지를 물리 메모리에서, 저장 매체로 내릴 것인가에 대한 것이 페이지 교체 정책이다.

1) FIFO 알고리즘

가장 먼저 들어온 페이지를 내린다. 

2) OPT(OPTimal) 알고리즘

앞으로 가장 오랫동안 사용하지 않을 페이지를 내린다. => 그러나 미래에 어떤 페이지를 얼마나 사용할 것인지는 알 수 없으므로 일반 OS에서는 구현이 불가하다. 

3) LRU(Least Recently Used) 알고리즘

가장 오래전에 사용된 페이지를 내리자 라는 아이디어로, OPT 알고리즘이 미래의 일을 알 수 없으므로 구현이 불가하므로, LRU에서는 과거 기록을 기반으로 시도한 것이다. 

4) LFU(Least Frequently Used) 알고리즘

가장 적게 사용된 페이지를 내리자. 

5) NUR(Not Used Recently) 알고리즘

LRU와 마찬가지로 최근에 사용하지 않은 페이지부터 내리자는 알고리즘인데, 각 페이지마다 참조 여부를 나타내는 비트(R), 수정 여부를 나타내는 비트(M)을 두어서 (0, 0), (0, 1), (1, 0), (1, 1) 순으로 교체한다.