MALLOC_MMAP_THRESHOLD_ と MALLOC_MMAP_MAX_
malloc(3) を呼んだ時、glibc はヒープ領域から指定したサイズのチャンクを確保するが、ヒープ領域が足りなかった場合 glibc は brk(2) を呼んでヒープ領域を拡張するか、Anonymous Memory と呼ばれる領域を mmap(2) して新たなヒープ領域を作成する。
この動作を制御する環境変数が MALLOC_MMAP_THRESHOLD_ らしいのでこれを試しているのだけれど、効かなくて困った。
しかたがないので glibc のソースを読んでいると mmap(2) を使用する最大サイズを指定する MALLOC_MMAP_MAX_ というのも見つけた、これはばっちり効いたのでこれを使おう。
1M を 3回 malloc するだけのコード
#include <stdio .h>
#include <stdlib .h>
int main(){
int i;
for(i=0;i<3;i++){
malloc(1*1024*1024);
}
return 0;
}
% strace ./a.out (略) mmap2(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7c9b000 mmap2(NULL, 2101248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7a9a000 mmap2(NULL, 3149824, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7799000
デフォルトではこんな風に、3回 mmap(2) が呼ばれる。
MALLOC_MMAP_MAX_=0 にすると、
% strace env MALLOC_MMAP_MAX_=0 ./a.out (略) brk(0) = 0x8efa000 brk(0x901b000) = 0x901b000 brk(0x911b000) = 0x911b000 brk(0x921b000) = 0x921b000
4回 brk(2) を呼ぶようになった。
MALLOC_MMAP_MAX_=1 にすると、
% strace env MALLOC_MMAP_MAX_=1 ./a.out (略) mmap2(NULL, 1052672, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7cfe000 brk(0) = 0x94bc000 brk(0x95dd000) = 0x95dd000 brk(0x96dd000) = 0x96dd000
最初の malloc(3) だけ mmap(2) するようになった。
単位はMbyte なのね。(MALLOC_TRIM_THRESHOLD_の単位は byte だったのに・・・)
これで完全に malloc(3) の中で mmap(2) を呼ぶこと無いかというと、そういう訳でもなくて、特定の条件下で mmap(2) する場合ある様なので困ったのう。
Permanent Link: http://www.cuspy.org/blog/archives/866
Trackback URL: http://www.cuspy.org/blog/archives/866/trackback
