linux | malloc

멀티 스레드 환경에서 메모리 할당자 비교 - tcmalloc, jemalloc, SLAB

멀티 스레드 환경에서 ptmalloc의 단편화 문제를 극복하기 위한 tcmalloc, jemalloc, nedMalloc, SLAB Allocator의 작동 방식과 적용 사례를 정리합니다.

Mimul
MimulApril 01, 2011 · 9 min read · Last Updated:

애플리케이션에서 메모리 사용은 필수 불가결하다. 그러나 메모리 사용 효율이나 성능을 잘 고려하지 않고 기본 malloc을 그대로 사용하는 경우가 많다. 트래픽이 많은 서비스에서는 메모리 사용에도 신경을 써야 한다.

메모리를 할당받기 위해 사용하는 malloc() 함수는 일반적으로 glibc에 포함된 메모리 할당자에서 구현되어 있다. 기본 메모리 할당자는 ptmalloc이다. 메모리 할당자의 역할은 brk/sbrk/mmap 등을 사용해 시스템으로부터 큰 메모리 영역을 할당받아 적절하게 분할하여 애플리케이션이 요청하는 메모리 할당을 처리하는 것이다.

하지만 빈번하게 메모리를 할당·해제하고 수십 개의 스레드가 동작하는 프로그램에서는 어쩔 수 없이 메모리 단편화(Memory Fragmentation)가 발생하여 메모리 사용량이 늘어난다. 규모가 큰 애플리케이션들은 glibc의 기본 메모리 할당자인 ptmalloc이 메모리 단편화 문제가 심하고, multi-thread, multi-processor에 대한 고려가 부족해 performance bottleneck이 존재하므로 다른 메모리 할당자를 사용하기도 한다.

1. 데이터 섹션(메모리 사용 구조)

  • 전역 메모리(Global Memory): 지역 함수(Local Function), 전역 변수(Global Variable), 정적 변수(Static Variable)
  • 스택 메모리(Stack Memory): 지역변수와 매개변수가 저장되는 곳. 컴파일 타임에 크기 결정. 메모리 생명 주기를 알기 때문에 단편화가 일어나지 않는다.
  • 힙 메모리(Heap Memory): 동적 메모리 할당을 위한 곳. 프로그래머가 할당 및 해제해야 한다. 런타임에 크기 결정. 메모리 생명 주기를 모르기 때문에 단편화가 일어난다.

컴파일러 및 링커가 메모리 할당 기능을 수행할 때에는 메모리 단편화가 일어나지 않는다. 컴파일러가 데이터의 수명을 알고 있기 때문이다. 메모리 할당자는 기본적으로 오버헤드, 내부 단편화, 외부 단편화 등 세 가지 측면에서 메모리를 낭비한다.

2. 메모리 낭비 종류

  • 오버헤드: 메모리 할당자는 할당 상태를 설명하는 일부 데이터를 저장해야 한다. 즉, 모든 자유 블록의 위치, 크기, 소유 정보, 그리고 내부 상태와 관련된 정보를 저장해야 한다. 일반적으로 할당자 자신이 관리하는 메모리 영역에 이런 오버헤드 정보를 저장한다.
  • 내부 단편화: 모든 메모리 할당 작업은 프로세서 아키텍처에 따라 4, 8, 16으로 나뉘는 주소에서 시작되어야 한다. 만약 클라이언트가 41바이트 블록을 요청하면 42, 48 또는 그 이상의 바이트를 얻게 된다. 클라이언트가 요청한 크기를 반올림한 결과 남게 되는 여분의 공간이 내부 단편화다.
  • 외부 단편화: 애플리케이션이 연속해서 세 블록을 할당한 후, 가운데를 해제하면 외부 단편화가 발생한다.

3. Memory Allocator 종류

  • tcMalloc: Google에서 만든 할당자. 작은 사이즈의 allocation에 최적화되어 있다.
  • jemalloc: Linux, macOS에 최적화. Firefox에서 사용한다.
  • nedMalloc: 오픈 소스. dlmalloc에 근간을 두며 Windows에 최적화되어 있다.

싱글 스레드 환경에서는 ptmalloc과 위의 메모리 할당자 간 성능 차이가 크지 않을 수 있다. 멀티 스레드 환경에서 위의 메모리 할당자를 사용함으로써 많은 성능 향상을 볼 수 있다.

4. tcMalloc 소개

  • 작동 방식(성능 향상 방식)
    • 중앙 메모리 관리자와 스레드별 메모리 관리자를 구분하고, 작은 크기(32K 이하)의 메모리 할당·해제 요청은 스레드별 메모리 관리자가 처리하며, 부족할 경우 중앙 메모리 관리자에서 얻어오는 방식으로 처리한다.
    • 큰 메모리(32K 이상)는 전역 관리자에서 페이지 크기(4K) 단위로 클래스를 나누어 mmap()을 이용하여 할당한다.
  • 지원 환경
    • Linux (32 and 64 bit), Windows (32 bit only), Solaris
    • NUMA-aware TCMalloc
  • 사용 사례
    • WebKit, MySQL, HyperTable, memcached

5. jemalloc 소개

  • 작동 방식(성능 향상 방식)
    • 스레드별 메모리 관리자 Arena와 작은 단위의 잦은 메모리 할당의 경우, arena를 참조하지 않고 바로 malloc할 수 있도록 각 스레드에 thread cache 영역을 두어 성능을 향상시킨다.
  • 지원 환경
    • Linux, Windows, macOS
  • 사용 사례
    • Firefox, Facebook

6. nedMalloc 소개

  • 작동 방식(성능 향상 방식)
    • dlmalloc에서 출발했고, 오픈 소스이며 내용은 간단하지만 성능도 좋다는 평으로 알려진다.
  • 지원 환경
    • Windows(32) 최적화됨, macOS, Linux
  • 사용 사례
    • 개인 사용자 위주. Windows 개발자들이 많이 채택하며 일부 JavaScript 엔진에 사용된다.

7. SLAB Allocator

  • 슬랩은 내부 단편화 문제를 해결할 뿐만 아니라 커널 내에서 흔히 일어나는 dynamic memory 할당의 오버헤드를 줄이기 위해 캐싱하는 역할을 하여 성능 개선에도 큰 도움을 준다.
  • 캐시는 관리가 필요한 오브젝트 종류별로(예: task_struct, file, buffer_head, inode 등) 작성되고, 그 오브젝트의 슬랩을 관리하며 슬랩은 하나 이상의 연속된 물리 페이지로 구성된다. 일반적으로 하나의 페이지로 구성된다. 캐시는 이러한 슬랩들의 복수 개로 구성된다.
  • 자주 사용되는 오브젝트들을 미리 할당해 두고, 사용자 요구가 있을 때마다 바로 반환한다. 물리 메모리를 확보하기 위한 검색·회수·반환 과정을 생략할 수 있어 시스템 성능이 향상된다. 또한 다 사용된 오브젝트들을 반납받아 커널의 메모리 할당자에게 반환하지 않고 보관했다가 재사용하기 때문에 성능을 더욱 높일 수 있다.

8. 응용 예(MySQL-tcMalloc)

MySQL 성능 향상을 위한 tcMalloc 적용 예:

# 64bit 머신일 경우에만 필요함. libunwind
$ wget http://download.savannah.gnu.org/releases/libunwind/libunwind-0.99-alpha.tar.gz
$ tar zxvf libunwind-0.99-alpha.tar.gz
$ cd libunwind-0.99-alpha/
CFLAGS=-fPIC ./configure
make CFLAGS=-fPIC
make CFLAGS=-fPIC install

$ wget http://google-perftools.googlecode.com/files/google-perftools-1.7.tar.gz
$ tar zxvf google-perftools-1.7.tar.gz
$ cd google-perftools-1.7/
$ ./configure
$ make && make install

$ vi /etc/ld.so.conf
/usr/local/lib 라인 추가
/sbin/ldconfig

$ vi /usr/local/mysql/bin/mysqld_safe
export LD_PRELOAD=/usr/local/lib/libtcmalloc.so

운영 환경이라면 LD_PRELOAD 방식보다 -ltcmalloc 방식으로 사용하는 것을 권장한다.

참고


Mimul

Written byMimul
Mimul is a programmer, technologist, exercise enthusiast and more.
Connect

Related SnippetsView All

Related ArticlesView All