mmapとかbrkとか

Linuxシステムコールプログラミング」(山森丈範著)で、Linuxにbrk/sbrk(2)というシステムコールがあるのを知った。

#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main() {
  char *s;

  if ((s = sbrk(13)) == -1) {
    perror("sbrk");
    return 1;
  }

  strcpy(s, "Hello World\n");
  write(1, s, 12);

  if (brk(s) < 0) {
    perror("brk");
    return 1;
  }

  return 0;
}

mallocの動作は「基本mmap」で細かなメモリ確保は違うということを聞いたことがあったけど、その辺を色々調べてみた。mmapはメモリ確保のためのシステムコールだと思ってたけど、そうではなくて、これはファイルをメモリにマップするもので、その特殊なケースとしてファイルをマップせずに0クリアしてメモリを動的に確保する目的でも使われる、とある。

A Memory Allocatorというあたりを読むと、色々と戦略が書かれていて面白い。glibcに入っているメモリアロケータはptmalloc3というもので、ダウンロードして眺めてみたけど、マルチスレッド対応とかでまったく読める気がしない。Win32とPOSIX、各種Unix対応のためにifdefだらけ。

しかし、ptmalloc.c以外にもmalloc.cが入っていて、眺めてみた。1992年から延々とメンテされてるコードだけあって、ドキュメントやコメントが非常に整備されていてこれまた読み物としてスゴい。

ぼくのディスク上には、どんなメモリアロケータがあるのかなと思って、

% locate malloc.c

とかやったら、

src/linux-2.6/mm/vmalloc.c
src/home/chrome-svn/tarball/chromium/src/third_party/tcmalloc/tcmalloc/src/tcmalloc.cc
:
:

とか出てきた。Chromeって自前のメモリアロケータだったのかと思って、ググったら、TCmallocの解説ができてた。ていうかGoogleのperftoolsに入ってるやつか。tcmallocはmalloc/freeが高速で、マルチスレッド時のロックがほとんどないとある。ふーん。glibc2.3で使われてるptmalloc2より6倍速いとか。ptmalloc3と比べるとどうなんだろうか。

いろんなアロケータの性能の話が気になって調べたら、Mozillaのjemallocもあるし、GTK+で使われてるGlib slice allocatorというのもあるらしい。ちょっと胡散臭いnedmallocとかも。どんなユースケースでも最速ということはありえないので本当に性能が重要ならアプリごとにアロケータを書けという議論もあるらしい。

ていうか、http://memoryallocators.com/ なんてサイトがあるのか。