본문 바로가기
OS & Network/OS

메모리[2] - 페이징, 가상메모리

by 코딩공장공장장 2024. 7. 25.

메모리 단편화


외부 단편화

 

첫번째 단계에서 process5, 8, 2가 할당되어있다.

process8을 종료 시켜 중간에 비어있는 메모리 영역을 확보하였다.

이후 process9를 실행시켜 메모리 영역에 할당하였고, 그런 다음 process5를 종료 시켜

마지막 단계처럼 두개의 비어있는 영역을 확보하였다.

 

이때, process8을 메모리에 할당할 수 있을까??

두 비어있는 영역을 합쳐놓으면 process8을 할당할 만큼 충분한 공간이지만 연속적으로 존재하지 않기에 메모리 영역에 할당하지 못한다.

 

이와 같이 메모리에 충분한 공간이 있지만 연속적으로 존재하지 않아 데이터를 할당하지 못하는 상황을 외부 단편화 라고 한다.

 

내부 단편화

 

내부 단편화는 메모리 영역을 여러 프레임으로 나누어 각 프레임에 프로세스를 나누어 할당 시킬 때,

프레임의 크기가 할당된 크기보다 커 유휴 메모리 공간이 남게되는 상황이다.

 

내부단편화는 해결방법이 없다.

외부 단편화를 해결하는 과정에서 새롭게 나타난 현상이지만 외부 단편화에 비해 단편화가 덜 발생한다.

 

페이징


페이징은 메모리 공간을 여러 프레임으로 나누어 프로세스를 각 프레임에 나누어 할당하는 방식이다.

프로세스의 물리적 주소가 연속적으로 존재하지 않아도 됨을 허용하는 메모리 관리 형식이다.

페이지 테이블을 통해 물리적 주소가 연속적으로 존재하지 않아도 접근을 할 수 있다.

페이지 테이블은 page number에 frame number가 매핑되어있는 구조로 이루어져 있기 때문이다.

페이지 테이블을 통한 주소 변환이 어떻게 이루어지는 보겠다.

 

[주소 변환 예제]

  1. 논리적 주소가 저장된 페이지 테이블 찾기
    논리 주소가 13000이라고 하고 페이지 크기가 4096 이라고 하자.
    * 페이지 번호 : 13000 / 4096 = 3
    * 페이지 오프셋 : 13000 % 4096 = 1712

  2. 페이지 번호와 매핑되는 프레임 시작 위치로 접근
    우리는 페이지 번호가 3번이라는 걸 알았다. 
    페이지 테이블을 확인하니 페이번호 3에 대응되는 프레임 번호는 7이다.
    7번 프레임의 시작 위치는 7*4096 = 28672 이므로 28672로 접근한다.

  3. 정확한 위치로 접근
    이전에 얻은 페이지 오프셋 값 1712를 프레임의 시작 주소 28672에 더함으로써 물리적 주소로 최종 변환될 수 있다.

 

페이징을 통한 메모리 공간을 나누어 관리하는 방식은 외부단편화를 해결한다.

작은 프레임 단위로 나누어 저장할 수 있으므로 연속 공간 할당에서 생기는 문제를 해결할 수 있다. 

다만, 할당한 크기보다 프레임 크기가 크면 내부단편화  현상이 발생하게 된다.

 

페이징은 메모리 공간의 효율적인 관리 뿐만 아니라 프로세스 보호의 목적도 존재한다.

페이지 테이블은 valid-invalid 비트를 두어 메모리 접근을 보호한다.

실행 시점 주소 바인딩이 일어나는 경우 논리적 주소에 해당하는 물리적 주소가 아직 메모리 영역에 존재하지 않을 수 있다.

이런 경우 valid-invalid bit에 0(i)라고 표시되어 있어 CPU의 메모리 접근을 뒤로 미루고 해당 데이터가 실제 메모리 영역에 할당 된 이후 valid-invalid bit가 1(v)로 표시된 이후 정상적으로 접근하게 할 수 있다.

 

페이지 테이블 저장 위치 - TLB


페이지 테이블을 어느 곳에 저장시키는냐에 따라 성능의 차이를 나타낼 수 있다.

페이지 테이블을 메모리에 저장시키면 페이지 테이블에 접근하고 페이지 테이블 통해 변환한 물리적 주소 접근까지 총 2번의 메모리 접근이 발생한다.

CPU에 저장하는것이 성능에 가장 좋지만 이미 CPU의 레지스터들은 다른 목적으로 사용되고 있고 페이지 테이블 또한 공간이 작은편이 아니기에 여유 공간이 없다.

 

이를 대체하기 위해 CPU 내에 페이지 테이블의 캐시 공간인 TLB를 두게 되었다.

TLB는 MMU 내에 존재하며 고성능 메모리 칩이다.

TLB는 페이지 테이블의 캐시 정보이다. 실제 페이지 테이블은 메모리 공간에 존재한다.

페이지 테이블을 CPU에 모두 저장하기에 그 용량이 크기 때문에 메모리에 모든 정보를 저장하고 

자주 사용되는 정보들만 TLB에 저장한다.

따라서 TLB에 페이지 테이블이 저장되어있으면 TLB에서 실제 물리적 주소로 바로 접근이 가능하고,

존재하지 않는다면 메모리의 페이지 테이블을 거쳐 물리적 주소로 접근하므로 성능이 떨어진다.
(이때 존재하지 않은 페이지 테이블을 TLB에 캐싱하는 처리도 진행함)

TLB는 대체적으로 95% 이상의 정보를 저장하고 있어 성능 향상에 큰 도움이 된다.

 

Swapping(메모리 스왑)


 

Swapping은 메모리에 적재되어 있는 프로세스 중에서 오랫동안 사용하지 않은 프로세스를 메모리에 존재하는 상태 그대로 디스크에 저장시켜 놓는 방식이다.

멀티 프로그래밍 환경에서 메모리 공간을 효율적으로 사용하기 위한 방식으로 사용 가능성이 낮은 프로세스는 디스크에 임시 저장시켜놓고 사용할 때, 다시 메모리에 할당하는 방식이다.

메모리에서 디스크로 내려가는 것을 swap-out, 디스크에서 메모리로 올라오는 것을 swap-in이라고 한다.

가상 메모리 환경에서는 page-out, page-in 이라고도 한다.

 

디스크라고 표현하였지만 정확하게는 Backing store이라는 디스크 내부에 메모리 스왑을 위해 마련한 공간이다.

Backing strore의 사이즈를 정함으로써 메모리 스왑 크기를 정할 수 있다.

스왑은 프로세스 전체를 대상으로 진행 할수도 있지만 프로세스의 일부인 페이지를 기준으로도 진행할 수 있다.

페이지 기준 스왑은 가상메모리 환경에서 사용된다.

 

가상메모리


가상 메모리는 프로세스 전체를 메모리에 적재하는 것이 아닌 필요한 부분만 적재하는 기법이다.

이는 프로그램의 크기가 메모리 크기보다 크더라도 실행될 수 있는 환경을 제공한다.

 

적재하는 단위는 페이지 단위이다.

필요한 페이지에 해당하는 프레임들을 적재하고 사용하지 않는 프레임은 backing store에 저장시켜놓는다.

이전에 설명한 메모리 스왑을 통해 진행된다.

 

Demand Paging


Demand Paging이라는 것은 메모리를 backing store로 부터 적재하는 전략이다.

페이지 요청이 일어났을 때, 메모리 공간에 부재하면 page-in 을 수행한다.

이때 메모리 공간에 존재하는지 여부는 valid-invalid bit로 비교한다.

 

페이지가 메모리에 존재하지 않는 상황을 예시로 Demand Paging 처리방식을 알아보겠다.

 

  1. 페이지 테이블의 valid-invalid bit 참조
    valid(1)인 경우 메모리에 데이터가 적재되어있으므로 바로 접근을 수행한다.

  2. invalid(0)인 경우 trap(Page fault 예외 발생)을 걸어 os에 page 부재를 알린다.
    이때 명령어 수행은 중단되고, 프로세스는 waiting queue에서 대기한다.

  3. os는 backing store에서 접근하여 페이지 이미지를 찾는다.

  4. free frame list에서 비어있는 프레임을 찾고 페이지를 할당한다.

  5. 페이지 테이블의 valid-invalid bit의 값을 valid(1)로 수정한다.

  6. trap으로 인해 interrupt 된 명령어를 다시 수행한다.
    이때 waiting que에 존재하는 프로세스를 ready que로 이동시키고 실행시킨다.

 

위와 같이 메모리에 페이지가 존재할 때와 존재하지 않을 때를 구분하고 Demand-Paging을 거쳐 프로세스를 수행시킬 수 있다.

허나, 위에서 설명하지 않은 상황이 존재한다.

페이지가 메모리에도 존재하지 않고 backing store에도 존재하지 않는 상황이다.

valid는 페이지가 메모리에 존재하는 상황을 의미한다.

invalid는 페이지가 메모리에 존재하지 않고 backing store에 존재하는 상황과 메모리와 backing store 모두에 존재하지 않는 상황을 포함한다. 

invalid 상황에서 위 두가지 경우의 구분은 trap을 걸어 OS에 페이지 부재를 알렸을 때,

OS가 backing store에 페이지가 존재하는지 여부를 통해 구분할 수 있다.

존재하면 그 다음 과정을 수행하고 존재하지 않는다면 프로세스는 종료된다.

 

페이지 교체 알고리즘


Demand paging 작업이 많이 일어나 메모리 공간이 가득차게 되면 더이상 swap-in을 수행할 수 없다.

이때는 기존에 적재된 프레임 중 backing store로 내려보낼 희생양(victim frame)을 선정해야한다.

 

 

페이지 교체는 page-in 뿐만 아니라 page-out 과정까지 포함하므로 두번의 IO 작업이 발생하므로 성능이 굉장히 떨어진다.

때문에 IO 작업을 최소화 시켜야하고 이를 위해 사용성이 가장 떨어지는 프레임을 victim frame으로 선정해야한다.

 

LRU(Least Recently Used) : 가장 오랫동안 사용되지 않은 페이지

페이지 교체에 사용되는 알고리즘으로 LRU가 존재한다.

별도의 reference bit를 하나 더 두어 참조관계가 발생했는지 여부를 체크한다.

최초 0으로 초기화 되어있고 참조가 발생하면 bit 값을 1로 설정한다.

페이지 교체 상황시 reference bit가 0인 것 중에 가장 먼저 들어온 프레임을 제거하게 된다.

 

반응형