странное поведение malloc с распределителем Doug Lea - PullRequest
1 голос
/ 25 мая 2011

У меня очень маленькая система с кучей всего 16 КБ, без mmap, без подкачки.Я использую последнюю версию 2.8.5 Doug Lea allocator ftp: //g.oswego.edu/pub/misc/malloc-2.8.5.c

ОБНОВЛЕНИЕ Я сделал меньший тестовый пример, который легче понять и понять, в чем моя проблема

Если я выделю 8 КБ, освободлю его, выделю 12 КБ, он работает (i! = NULL), я могу выделить12 КБ:

char *i;
dlstats();
i = dlmalloc(8192);
printf("DEBUG: %p\n", i);
dlstats();
dlfree(i);
dlstats();
i = dlmalloc(12288);
printf("DEBUG: %p\n", i);
dlstats();
dlfree(i);
dlstats();

отображает:

heap 0xa00003f0 sbrk 0xa00003f0 arena 0 ordblks 0 usmblks 0 uordblks 0 fordblks 0 keepcost 0
DEBUG: 0xa00003f8
heap 0xa00003f0 sbrk 0xa0002440 arena 8272 ordblks 1 usmblks 8272 uordblks 8200 fordblks 72 keepcost 32
heap 0xa00003f0 sbrk 0xa0002440 arena 8272 ordblks 1 usmblks 8272 uordblks 0 fordblks 8272 keepcost 8232
DEBUG: 0xa00003f8
heap 0xa00003f0 sbrk 0xa0003460 arena 12400 ordblks 1 usmblks 12400 uordblks 12296 fordblks 104 keepcost 64
heap 0xa00003f0 sbrk 0xa0003460 arena 12400 ordblks 1 usmblks 12400 uordblks 0 fordblks 12400 keepcost 12360

Если я сначала выделю слишком большой буфер (30 КБ), а затем выделю 8 КБ, освободлю его, выделю 12 КБ, это работает (i == NULL), i не может выделить 12 КБ:

char *i;
dlstats();
i = dlmalloc(30000);
printf("DEBUG: %p\n", i);
dlstats();
i = dlmalloc(8192);
printf("DEBUG: %p\n", i);
dlstats();
dlfree(i);
dlstats();
i = dlmalloc(12288);
printf("DEBUG: %p\n", i);
dlstats();
dlfree(i);
dlstats();

отображает:

heap 0xa00003f0 sbrk 0xa00003f0 arena 0 ordblks 0 usmblks 0 uordblks 0 fordblks 0 keepcost 0
DEBUG: 0x0
heap 0xa00003f0 sbrk 0xa00003f0 arena 0 ordblks 0 usmblks 0 uordblks 0 fordblks 0 keepcost 0
DEBUG: 0xa00003f8
heap 0xa00003f0 sbrk 0xa0002430 arena 8256 ordblks 1 usmblks 8256 uordblks 8200 fordblks 56 keepcost 16
heap 0xa00003f0 sbrk 0xa0002430 arena 8256 ordblks 1 usmblks 8256 uordblks 0 fordblks 8256 keepcost 8216
DEBUG: 0x0
heap 0xa00003f0 sbrk 0xa0002430 arena 8256 ordblks 1 usmblks 8256 uordblks 0 fordblks 8256 keepcost 8216
heap 0xa00003f0 sbrk 0xa0002430 arena 8256 ordblks 1 usmblks 8256 uordblks 0 fordblks 8256 keepcost 8216

В каждый момент времени выполняется только одно выделение и освобождаетсяперед выделением другого блока, поэтому память никогда не должна быть фрагментирована.

Ответы [ 2 ]

4 голосов
/ 26 мая 2011

У меня был ответ от Дуга Ли:

Если попытка расширить (или инициализировать) непрерывный сегмент sbrk не удалась, sysalloc помечает пространство как несмежное, чтобы избежать постоянных повторных сбоев, которыев противном случае прервет переходы из MORECORE в MMAP, если он будет доступен.

Это приведет к невозможности объединения последующих сегментов.В настоящее время нет способа изменить это поведение.Но вы должны быть в состоянии обойти это, удалив строки 4113-4

  else
    disable_contiguous(m); /* Don't try contiguous path in the future */

В будущем я рассмотрю возможность добавления способа управления этим в ходе некоторых другихплановая поддержка защиты страницы

1 голос
/ 25 мая 2011

Я думаю, что этот параграф (из википедии, так что никаких гарантий) объясняет, почему вы наблюдаете такое поведение:

У dlmalloc довольно слабый алгоритм объединения пакетов в свободном пространстве, главным образом потому, что объединение свободного пространства имеет тенденциюбыть очень медленным из-за истощения кеша TLB.Он вызывается каждые (по умолчанию) 4096 операций free () и работает путем итерации каждого из сегментов, ранее запрошенных системой, которые не были непрерывно возвращены системой.Он пытается идентифицировать большие диапазоны памяти, которые не содержат выделенных блоков, и разбивает свой сегмент на две части, возвращая свободную память в систему.Этот алгоритм хорошо работает, если dlmalloc является единственным пользователем системы ВМ, однако, если dlmalloc используется одновременно с другим распределителем, объединитель свободного пространства dlmalloc может не правильно определить возможности для освобождения свободной памяти.

http://en.wikipedia.org/wiki/Malloc#dlmalloc_and_its_derivatives

...