본문 바로가기

리눅스 커널 Linux kernel

4장 메모리관리 - 2

 

4. 가상메모리 기법

리눅스에서 태스크를 관리하는 자료구조는 task_struct 자료구조 입니다.

이 task_struct 자료구조와 태스크의 가상 주소 공간의 관계에 대해 알아보겠습니다.

가상 메모리 관련 정보는 task_struct안의 mm필드에서 관리합니다. 이 필드는 크게 세 부분으로 나뉘어질 수 있습니다.

vm_area_struct구조체

태스크 구성, 같은 속성을 갖는 연속된 영역 region으로 관리

pgd

페이지 디렉터리의 시작점 주소

가상메모리 구조 변수

 

vm_area_struct : 세그먼트의 시작주소, 끝 주소, region의 접근제어 플래그 변수

┕ 이 세그먼트가 실제 실행 파일의 어느 위치에 있는지에 대한 정보를 vm_file와 vm_offset 변수로 관리하고, 페이지 폴트가 발생하면 어떤 파일의 어느 부분을 읽을지 결정합니다.

물리메모리의 page frame과 마찬가지로 가상메모리도 일반적으로 4KB의 페이지 단위의 고정된 크기로 할당합니다.

공통된 속성의 page들이 모여 vm_area를 구성하고 이를 vm_area_struct로 관리합니다. 결국 가상메모리의 할당/해제 문제는 vm_area_struct의 할당/해제문제와 page의 할당/해제 문제 두 가지로 정리됩니다.

하나의 태스크에는 여러 개의 vm_area_struct가 존재해 인접한 vm_area_struct의 속성이 같다면 합쳐져서 관리할 수 있습니다.

 

5. 가상메모리와 물리메모리의 연결 및 반환

가상메모리와 물리메모리의 연결 및 반환 과정을 살펴보기 위해선 프로그램의 시작과정을 살펴보아야 합니다. 프로그램이 시작되면 태스크가 생성되고 그 태스크에게 가상 주소 공간을 제공합니다. 이때 물리 메모리의 일부를 할당하여 태스크가 원하는 디스크 상의 내용을 물리메모리 적재하게 됩니다. 이렇게 물리 메모리의 실제 주소와 태스크의 가상 주소 공간이 연결되게 됩니다.

가상 메모리 기법의 도입으로 가상 주소와 물리 주소는 단위를 부르는 명칭도 달라졌습니다. 가상 주소의 최소할당 단위는 '페이지'이고 물리 주소의 최소할당 단위는 '페이지 프레임'입니다. 가상주소와 물리주소의 관계는 페이지 테이블을 통해 연결됩니다. '페이징'은 페이지 테이블을 통해 가상 주소를 물리 주소로 변환하는 것을 말합니다. 가상 메모리 기법의 도입으로 필요한 메모리만 물리 메모리에 적재된다고 앞서 언급이 되었었는데, 여기서 수행에 필요한 일부 페이지만을 적재하고 나머지는 필요할 때 페이지 폴트 처리를 하여 요구 페이징(demand paging)으로 물리 메모리의 필요한 부분만을 사용하여 많은 태스크들이 동시에 물리메모리에 적재될 수 있게 됩니다.

리눅스에선 3단계 페이징 구조를 거쳐 가상 주소가 물리 주소로 변화합니다. 실제 CPU에선 가상주소로부터 물리주소로의 변환을 담당하는 별도의 하드웨어 MMU(Memory Management Unit)을 갖습니다. 리눅스 3단계 페이징 실제 동작을 살피기 전에 먼저 태스크가 생성되면 갖는 task_struct 자료구조 안에 mm_struct mm 필드가 태스크의 메모리 공간과 관련된 필드를 많이 가지고 있습니다. mm_struct안의 pgd 필드는 가상주소를 물리주소로 변환하기 위한 시작점인 PGD(Page Global Directory)의 페이지 프레임 번호를 갖습니다. 이를 통해 32/64bit에 따라 가상 주소 중 일부를 이용해 인덱싱 하면 PMD(Page Middle Directory)를 얻고 다시 가상 주소 중 일부를 이용하여 인덱싱 해 PTE(Page Table Entry)를 얻습니다. PTE 가상 주소 중 일부를 이용해 인덱싱하면 실제 접근하게 될 페이지 프레임 주소를 얻을 수 있습니다.

 

6. 커널 주소 공간

커널의 경우 자신을 위한 페이지를 시스템의 부팅 시점에 미리 작성해 놓습니다.

 

7. 리눅스와 64bit CPU

기존의 리눅스 3단계 페이징 구조로는 무리가 있어 4단계 페이징을 지원합니다. 메모리 자체도 많은 공간이 남아 비워둔 상태라고 합니다.

 

8.Lazy Buddy, Slub, Slob

큰 페이지를 매번 쪼개서 할당/해제하는 것은 Buddy할당자가 관리하는 비트맵 구조입장에서 오버헤드가 많습니다. 그래서 Lazy Buddy가 도입되어 비트맵 구조 관리 작업을 뒤로 미루었습니다. 나중으로 미루었다는 것입니다. 여기서 말하는 나중이란 가용메모리가 부족해지는 시점을 말합니다. 이를 구현하기 위해 자료구조의 쓰임새에 변동이 수반되었습니다.

앞서 나온 Slab 할당자도 CPU당, node 당 별도의 캐시를 유지하다보면 규모가 커질수록 메타데이터가 증가할 수 밖에 없습니다. 그래서 Slub할당자가 도입되어 단지 구조체의 필드만을 이용해 관리를 하도록 하였습니다. Slob 할당자의 경우엔 아주 작은 상황을 고려하여 만들어졌습니다. 우분투를 설치하는 과정에서 Slab/Slob/Slub을 설정할 수 있는 것으로 알려졌습니다.