ptmalloc2 본문
https://dreamhack.io/learn/98#4
ptmalloc의 구현 목표는 메모리의 효율적인 관리입니다. 이 한 문장에는 여러 세부 목표가 함축되어 있습니다. 그중 핵심을 추려보면 다음과 같습니다.
- 메모리 낭비 방지
- 빠른 메모리 재사용
- 메모리 단편화 방지
ptmalloc2는 청크를 주요 객체로 사용한다.
prev_size | 8바이트 | 인접한 직전 청크의 크기. 청크를 병합할 때 직전 청크를 찾는 데 사용됩니다. |
size | 8바이트 | 현재 청크의 크기. 헤더의 크기도 포함한 값입니다. 64비트 환경에서, 사용 중인 청크 헤더의 크기는 16바이트이므로 사용자가 요청한 크기를 정렬하고, 그 값에 16바이트를 더한 값이 됩니다. |
flags | 3비트 | 64비트 환경에서 청크는 16바이트 단위로 할당되므로, size의 하위 4비트는 의미를 갖지 않습니다. 그래서 ptmalloc은 size의 하위 3비트를 청크 관리에 필요한 플래그 값으로 사용합니다. 각 플래그는 순서대로 allocated arena(A), mmap’d(M), prev-in-use(P)를 나타냅니다. prev-in-use 플래그는 직전 청크가 사용 중인지를 나타내므로, ptmalloc은 이 플래그를 참조하여 병합이 필요한지 판단할 수 있습니다. 나머지 플래그에 대해서는 여기서 설명하지 않겠습니다. |
fd | 8바이트 | 연결 리스트에서 다음 청크를 가리킴. 해제된 청크에만 있습니다. |
bk | 8바이트 | 연결 리스트에서 이전 청크를 가리킴. 해제된 청크에만 있습니다. |
bin🗑️
bin은 문자 그대로, 사용이 끝난 청크들이 저장되는 객체입니다. 메모리의 낭비를 막고, 해제된 청크를 빠르게 재사용할 수 있게 합니다.
ptmalloc에는 총 128개의 bin이 정의되어 있습니다. 이 중 62개는 smallbin, 63개는 largebin, 1개는 unsortedbin으로 사용되고, 나머지 2개는 사용되지 않습니다.
smallbin
32byte~1024byte사이의 청크들이 보관된다.
원형 이중 연결리스트 구조이며, FIFO이다.
unlink과정을 진행한다.
메모리상 인접한 두 청크가 해제되어 있고, smallbin에 있으면 병합된다.
fastbin
ptmalloc은 어떤 크기를 정하고, 이보다 작은 청크들은 fastbin에 저장한다.
리눅스에서는 32byte~128byte 청크들은 fastbin에 들어간다.
병합과정을 하지 않는다.
단일 연결리스트이므로 unlink를 수행 하지 않는다.
LIFO 방법을 사용한다.
largebin
1024byte이상의 청크들을 보관
best-fit으로 재할당, 청크를 내림차순으로 정렬
이중연결리스트, unlink도 동반된다.
연속된 largebin청크들은 병합된다.
unsortedbin
fastbin에 들어가지 않은 청크들은 unsortedbin에 들어간다.
원형 이중 연결리스트이며, 내부적으로 정렬 하지 않는다.
smallbin 크기에 해당하는 청크를 할당 요청하면, ptmalloc은 fastbin 또는
smallbin을 탐색한 뒤 unsortedbin을 탐색한다.
largebin의 크기에 해당하는 청크는 unsortedbin을 먼저 탐색한다.
arena
fastbin, smallbin, largebin 등의 정보를 모두 담고 있는 객체
레이스 컨디션을 막을 수는 있지만, 병목 현상 발생
tcache
glibc 2.26에 도입되었다. 멀티 쓰레드 환경에 더욱 최적화된
메모리 관리 메커니즘을 제공한다.
fastbin과 같은 LIFO방식을 사용, 단일 연결리스트
32byte~1040byte의 청크들을 보관
tcache가 가득 찬 경우 적절한 bin으로 분류
7개의 청크만 보관 가능
'개념 정리' 카테고리의 다른 글
PE 기초 개념 (0) | 2022.01.15 |
---|---|
shellcode 모음 (0) | 2022.01.07 |
셸코드 작성 (0) | 2021.12.30 |
어셈블리어와 x86-64 (0) | 2021.12.26 |
Linux Memory Layout (0) | 2021.12.26 |