3 ms·
This is correct. malloc_trim() can make the unused memory pages (within an mmap() that malloc did) available for use by other processes using madvise() (turning
by nh2 6y ago
This is correct. malloc_trim() can make the unused memory pages (within an mmap() that malloc did) available for use by other processes using madvise() (turning them from grey squares into white squares in the linked article's visualisation), but it does leave holes in the address space.
This is what the MMAP_THRESHOLD tunable solves. It makes that allocations larger than that many Bytes are served via their own mmap that can be munmapped in independence.
I use env MALLOC_MMAP_THRESHOLD_=65536 to reduce the memory-fragmentation wasted RAM of my program from 6.5 GB to 0.8 GB.
The benefit of this is that you don't have to decide at which points to call malloc_trim(). But it's expected to be a bit slower because mmap() takes a while. Choosing between malloc_trim() vs MALLOC_MMAP_THRESHOLD_ is dual to choosing between GC vs reference counting -- higher memory use for a while and having to choose when to clean up vs higher per-operation cost.
- labawi 6y agoIsn't this just passing work to the kernel which coincidentally behaves in a friendlier way than default malloc, so in essence a workaround for a bad/buggy allocator that doesn't release or reuse pages? If large allocations are page-aligned (hopefully at 16+ pages), they can be individually unmapped and remapped, and I see no reason why or how individual mmaps could in general result in less fragmentation, other than said silly malloc.
- nh2 6y agoI think you're pretty much right. E.g. https://github.com/thestinger/allocator/tree/f42a6c2dffb63d5aec3c9d7f6a387ee1c7b1857a#current-implementation https://github.com/thestinger/allocator/tree/f42a6c2dffb63d5... (found via Google) explains: > The Linux kernel also lacks an ordering by size, so it has to use an ugly heuristic for allocation rather than best-fit. It allocates below the lowest mapping so far if there and room and then falls back to an O(n) scan. This leaves behind gaps when anything but the lowest mapping is freed, increasing the rate of TLB misses. So the libc should be able to do a better job than the kernel here. And yes, I think it should probably work via MADV_DONTNEED to give mapped pages back to the kernel (and perhaps PROT_NONE to also reduce commit charge when overcommit is disabled, see https://github.com/thestinger/allocator/issues/18 https://github.com/thestinger/allocator/issues/18). I'm using `MALLOC_MMAP_THRESHOLD_` because it has a positive effect, but as written on https://news.ycombinator.com/item?id=24244271 https://news.ycombinator.com/item?id=24244271, I'm not sure why automatic trimming (which should do all of the discussed above) does not work.