Doug Lea分配器产生奇怪的malloc行为

| 我有一个非常小的系统,只有16kb的堆,没有mmap,没有交换。我正在使用最新版本的Doug Lea分配器2.8.5 ftp://g.oswego.edu/pub/misc/malloc-2.8.5.c UPDATE我制作了一个较小的测试用例,它更易于理解并查看我的问题是什么 如果我分配8kb,释放它,分配12kb,它就可以工作了(i!= NULL),我可以分配12 kb:
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
如果我先分配了一个太大的缓冲区(30kb),然后又分配了8kb,释放它,分配了12kb,则它正在工作(i == NULL),我无法分配12 kb:
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
在每一刻,只有一个分配被分配并释放,然后再分配另一个块,因此永远不要将内存碎片化。     
已邀请:
我得到了道格·李的回答:   如果尝试扩展(或   初始化)连续的sbrk段   失败,sysalloc将空间标记为   非连续的,避免连续的   否则会失败   中断从MORECORE到   MMAP可用时。      这将导致后续的段不   可合并。目前没有   覆盖此行为的方法。但是你   应该能够解决它   删除线4113-4
  else
    disable_contiguous(m); /* Don\'t try contiguous path in the future */
  以后,我会考虑添加一个   在控制过程中的方法   其他一些计划的支持   页面保护     
我认为这一段(来自维基百科,因此不能保证)解释了为什么您看到这种行为:   dlmalloc具有相当弱的可用空间段合并算法,主要是因为由于导致TLB缓存耗尽而导致可用空间合并非常缓慢。它被称为每个(默认情况下)4096个free()操作,并且它通过迭代先前从系统请求的,系统未连续返回的每个段来工作。它尝试识别不包含已分配块的大范围内存,并将其段分成两部分,并将空闲内存返回给系统。如果dlmalloc是VM系统的唯一用户,则此算法效果很好,但是,如果dlmalloc与另一个分配器同时使用,则dlmalloc的可用空间合并器可能无法正确识别释放可用内存的机会。 http://en.wikipedia.org/wiki/Malloc#dlmalloc_and_its_derivatives     

要回复问题请先登录注册