정보공간_1

[Linux] <Session 2> 물리 메모리 관리 본문

IT 놀이터/IT Storehouse

[Linux] <Session 2> 물리 메모리 관리

알 수 없는 사용자 2011. 6. 13. 22:17


안녕하세요 여러분

요새 포스팅이 늦었는데 ㅠㅠ 죄송합니다

이번에는 물리 메모리 관리와 관련된 부분을 보고자 합니다

물리메모리라고 하는 자원을 어떻게 관리할 것인가는, 메모리관리 중에서도 가장 기본이 되는 부분입니다.

물리 메모리는 물리페이지 단위로 관리됩니다. 여기에서는 리눅스 커널이 물리페이지를 관리하기 위해 어떠한 제어구조를 이용한다

앞으로 페이지라고 표현할 경우 물리 페이지를 의미하게 됩니다.


물리 페이지는 기본적으로 3개의 구조체에 의해 관리가 됩니다.

 - Page 구조체

page 구조체는 페이지 상태를 관리합니다. 이것은 페이지 1개에 대해 1개가 존재합니다.
page 구조체는 페이지 프레임 번호를 인덱스로 하는 배열로 되어있다.
이는 페이지 프레임 번호에 의해 page 구조체를 구할 수 있도록 하기위함이다.
페이지 구조체 멤버중에 가장 중요한 것 중에 flag멤버로 페이지의 상태를 나타낸다
페이지의 상태는 비트 단위로 의미가 있습니다. 그내용은 각자 알아서 찾아보세요

page 구조체는 매우 빈번하게 사용되기 때분에 가능한 한 최적화된 크기를 요구합니다.
최근의 머신은 물리 메모리의 탑재량도 많아지고 있기 때문에 page 구조체로 소비되는 메모리 량을 줄이려는 의도에서 최적화가 요구된다.

 - Zone 구조체

페이지는 주소의 범위에 따라 4개의 zone으로 분류 됩니다. 386, 486에서 사용되던 ISA 슬롯을 사용하는 디바이스는 DMA에 0~16M만 사용 가능합니다.
이를 위해 할당된 공간이 ZONE_DMA입니다. ZONE_DMA32는 32비트 이하의 주소 범위를 의식할 필요가 있는 아키텍쳐에서 사용되고 있습니다.
ZONE_HIGHMEM은 커널 공간에 직접 엑세스 할 수 없어던 영역을 나타내는 것입니다. ZONE_HIGHMEM은 64비트 아키텍처에서는 불필요하기 때문에 사용되고 있지 않다

 - pglist_data 구조체

pglist_data 구조체는 노드별로 메모리를 관리하기 위한 제어표이다.
노드라고 하는 것은 시스템 내의 메모리를 분할하고, 메모리를 할당하는 방법에 차이를 두기 위한 것입니다.

그럼 이제 각 구조체 사이의 관계에 대해 알아 볼텐데요


각 구조체의 관계는 다음과 갔습니다.

pgdat_list -> pglist_data(node_zones 포함) 구조체 -> page 구조체 배열
    -> pglist_data 구조체 -> page 구조체 배열
           -> pglist_data 구조체 -> page 구조체 배열
  .  
  .  
  .  
  .  
           -> pglist_data 구조체 -> page 구조체 배열

이런 형태로 구조가 되어 있습니다. 각각의 구조체는 연결 리스트로 이루어져있으며 이를 통해 각각의 멤버들의 값을 읽고 쓸수 있게 됩니다.

 

*** 빈 테이지의 관리 ***
다른 OS처럼 리눅스도 이용가능한 메모리를 빈페이지로 관리합니다. 그리고 이런 빈페이지는 버디 시스템이라고 하는 구조로 관리되고 있습니다.

- 버디시스템 (버디할당자)

버디시스템은 빈페이지를 2의 거듭제곱 단위로 관리합니다. 즉 페이지를 1, 2, 4, 8, ... ... 페이지 단위로 관리하는 형태입니다.
연속하는 페이지는 가능한 큰 단위로 관리하지만, 지수의 페이지 경계에 맞춰 한곳으로 모아서 관리하는 것이 주요포인트 입니다.

버디시스템의 제어 구조는 zone 구조체의 frea_area멤버로 표시됩니다.
 - struct free_area free_area[MAX_ORDER];
배열의 인덱스는 지수에 대응합니다. 버디라고 하는 것은 어찌보면 부할하는 의미이기도 하지만, 이것을 1개 위의 지시로 정리할 때는 반대의 의미를 갔습니다.
예를들어 지수가 0인 경우, 페이지 0을 분할 하면 페이지 1이 됩니다. 페이지 0과 1이 모드 빈영역이 되면 그것들을 합쳐서 지수 1의 빈 영역으로 관리할 수 있습니다.
물론 비트맵을 만들어서 그속에서 페이지 관리가 이루어 지고 있습니다. 물론 커널 버젼에 따라 방식의 차이는 존재합니다.

 
여기서 잠깐 버디시스템에 대한 자세한 얘기를 더 해보도록하겠습니다.

버디 시스템은 여유 공간 격리 리스트의 일종의 변종으로 볼 수 있는 방법으로, 제한적이지만 효과적인 여유 공간 블록 분할Splitting과 병합을 지원한다. 버디 시스템 역시 분할과 병합에 사용하는 전략에 따라서 몇 가지 변이가 있다.

 

바이너리 버디 Binary Buddies에서는 전체 힙을 하나의 블록으로 보고, 요청에 맞는 블록이 발견될 때까지 각 블록을 둘로 분할하는 것을 반복하여 할당을 처리하고, 할당으로 인해 둘로 나눠진 블록이 모두 해제되면 다시 원래대로 하나의 블록으로 병합하는 것을 반복하는 방식으로 메모리 할당을 처리한다. 여기서 둘로 나눠져서 이후에 다시 합쳐질 대상이 되는 블록은 서로를 버디Buddy라고 간주한다. 즉 버디는 버디 시스템의 할당 트리 공간 상에서 형제Sibling에 해당하는 노드를 의미한다. 바이너리 버디의 가장 큰 문제는 할당 요청을 무조건 2의 승수 크기로만 할당하기 때문에 발생하는 내부 단편화다.

피보나치 버디Fibonacci Buddies에서는 앞의 두 숫자를 합쳐서 다음 숫자가 나온다는 피보나치 수열의 특성을 이용하여, 분할 크기가 피보나치 수열의 앞쪽 숫자가 되도록 공간을 분할하여 바이너리 버디에서와 같은 큰 내부 단편화를 줄이기를 시도한다. 일반화된 피보나치 버디Generalized Fibonacci Buddies는 피보나치 수열보다 분할 횟수에 따른 블록의 크기가 더 적게 나는 수열을 설정하여 분할 및 병합하는 방식이다. 피보나치 버디의 가장 큰 단점은 나뉘어진 메모리 크기가 다르기 때문에, 같은 크기의 할당 요청이 빈번하게 일어날 경우에 약하다는 점이다.

가중치 버디Weighted Buddies에서는 숫자에 따라서 다른 두 가지의 분할 및 병합 방법을 사용한다. 이 방법에서 2의 승수 크기인 공간은 둘로 나눠지지만 2의 승수의 3배 크기의 공간은 1/3 크기의 공간과 2/3 크기의 공간으로 나눠진다. 가중치 버디는 일반적인 버디 시스템보다 유연성이 뛰어나다는 장점이 있다.

더블 버디Double Buddy는 말 그대로 두 개의 버디 시스템을 동시에 운영하되, 한 쪽은 바이너리 버디를, 다른 한 쪽은 2의 승수의 고정된 배수(3이라면 3, 6, 12, 24, …)의 크기를 사용하는 버디 시스템을 사용하는 것이다. 바이너리 버디에 비해서 내부 단편화를 반 수준으로 줄일 수 있는 반면, 두 버디 시스템 간의 여유 공간 블록의 병합이 불가능하기 때문에, 애플리케이션의 할당 요청이 한 쪽 버디 시스템에만 치중될 경우 다른 쪽 버디 시스템이 이미 준비해둔 여유 공간 때문에 심각한 외부 단편화를 겪을 수 있다는 점이다.

 [출처: http://beforu.egloos.com/1165105]