Anonymous Memory Mapping (=AMM)


AMM은 Kerenl로부터 직접 메모리영역을 할당받는 기법으로, Heap을 거치지 않는다.

Heap영역 외의 공간에서부터 메모리를 할당받기 때문에 Heap에 메모리를 할당할 시 발생할 수 있는 Memory Fragmentation을 방지한다.

또, 커널에서 직접 할당해주는 메모리 공간이기에 zero filled 되어있다. 비록 Heap에 직접 접근하는 것보다 공간 할당에 있어서 더 느리다지만 memset으로 Heap을 초기화하는 오버헤드까지 고려하면 오히려 AMM이 더 빠를 수 있다.

할당 후 언제든지 할당공간의 크기를 재설정 할 수 있다는 것도 또 하나의 장점이다.

대게 이러한 특징들 때문에 대용량의 메모리 할당이 필요한 경우에 자주 쓰인다.


그런데 약간 문제가 있는 것이, BSD나 구버전의 Solaris(혹은 UNIX)기반 커널은 AMM을 지원하지 않는다.

이 러한경우 /dev/zero(swap영역으로 자주 쓰임, 가상파일)을 이용해서 Memory Mapping을 한다. 즉, AMM을 흉내라도 내보겠다는 것. 물론 /dev/zero의 file descriptor를 불러오는 것도 필요하고, 실제 AMM에 비해서 약간 느리기는 하다.

여기서는 두가지 기법 모두 기술하겠다.


[AMM]



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#define NULL 0
 
int main()
{
    const long szAlloc = sizeof("Hello Anonymous Memory Mapping!");
    char *ptr;
    int loop;
 
    ptr = mmap(NULL, szAlloc, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -10);
    if(ptr = MAP_FAILED)perror("mmap");
    ptr = "Hello Anonymous Memory Mapping!";
    printf("%s\t",ptr);
    return 0;
}
cs



[AMM /dev/zero]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#define NULL 0
 
int main()
{
    const long szAlloc = sizeof("Hello Anonymous Memory Mapping!");
    char *ptr;
    int fd = -1, loop;
 
    if((fd = open("/dev/zero", O_RDWR, 0))<0)perror("open");
    ptr = mmap(NULL, szAlloc, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
    if(ptr = MAP_FAILED)perror("mmap");
    ptr = "Hello Anonymous Memory Mapping!";
    printf("%s\t",ptr);
    return 0;
}
cs


Posted by RevDev
,