[Linux] Slab Memory Allocator
개요
Linux Kernel
에서 Slab Memory Allocator
란 user단에서 ptmalloc
과 같이 Kernel에서 사용되는 동적 메모리 할당자 입니다. ex) kmalloc()
- Slab Cache: 자주 사용되는 크기에 대한 동적 메모리를 미리 확보하고 관리하는 역할
- Slab Object: Slab Cache가 할당해 놓은 메모리 블록.
- Slab Page: Slab Object로 구성된 페이지
종류
Slab Memory Allocator
에는 크게 다음과 같이 3종류가 사용되고 있습니다. 이 중, 해당 포스터에서 별도의 언급이 없으면 Slab Memory Allocator
는 Slub
를 의미한다고 생각하시면 됩니다.
- Slab
- Slub
- Slob
💡 Linux Kernel에서 Slub가 Default로 사용되기 때문에 해당 내용만 다루겠습니다!
kmalloc 할당 과정
kmalloc
해당 함수는 다음과 같이 정의되어 있습니다. 할당하는 size가 KMALLOC_MAX_CACHE_SIZE
보다 크다면 kmalloc_large
함수가 호출되고 아니라면 kmalloc_trace
함수가 호출됩니다.
💡 kmalloc_index 함수는 size의 크기에 따라 index를 반환해주는 함수 입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static __always_inline __alloc_size(1) void *kmalloc(size_t size, gfp_t flags)
{
if (__builtin_constant_p(size) && size) {
unsigned int index;
if (size > KMALLOC_MAX_CACHE_SIZE)
return kmalloc_large(size, flags);
index = kmalloc_index(size);
return kmalloc_trace(
kmalloc_caches[kmalloc_type(flags, _RET_IP_)][index],
flags, size);
}
return __kmalloc(size, flags);
}
kmalloc_trace
kmalloc_trace
함수는 다음과 같이 slab_alloc_node
함수를 호출합니다.
1
2
3
4
5
6
7
8
9
10
11
void *kmalloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size)
{
void *ret = slab_alloc_node(s, NULL, gfpflags, NUMA_NO_NODE,
_RET_IP_, size);
trace_kmalloc(_RET_IP_, ret, size, s->size, gfpflags, NUMA_NO_NODE);
ret = kasan_kmalloc(s, ret, size, gfpflags);
return ret;
}
EXPORT_SYMBOL(kmalloc_trace);
kmem_cache
Slab Memory Allocator는 kmalloc_caches[]
라는 전역 배열을 사용해서 각 크기별 Slab Cache
를 관리합니다. 각 Slab Cache는kmem_cache
구조체로 이루어있고, 위의 할당 과정을 보면 해당 구조체가 사용된 것을 확인할 수 있습니다.
1
2
3
kmalloc_trace(
kmalloc_caches[kmalloc_type(flags, _RET_IP_)][index],
flags, size);
이렇게 Slab Cache
를 통해서 메모리를 효율적으로 관리하는 것을 확인할 수 있습니다.
This post is licensed under CC BY 4.0 by the author.