Description
Long-running processes frequently encounter internal fragmentation over time, where numerous pages in a page queue remain underutilized. In extreme or synthetic cases, this fragmentation can lead to memory commitment levels 10x higher than actual usage.
Since mimalloc (or any other allocator) cannot compact memory without application-level cooperation, the Dragonfly project addresses this by triggering an asynchronous defragmentation process. btw, #1220 is related to how we recognize that the defragmentation should kick-off. Defragmentation task scans iteratively a pool of objects in each thread and reallocates them if their backing page's utilization falls below a specific threshold.
To facilitate this, we have patched mimalloc to include the function below. I suggest adding this (or a similar implementation) to the advanced heap API.
bool mi_heap_page_is_underutilized(mi_heap_t* heap, void* p, float ratio) mi_attr_noexcept {
mi_page_t* page = _mi_ptr_page(p); // Get the page containing this pointer
mi_heap_t* page_heap = (mi_heap_t*)(mi_atomic_load_acquire(&(page)->xheap));
// Verify the heap matches and the page is not already marked as full
if (mi_likely(page_heap == heap && page->flags.x.in_full == 0)) {
// If the page is the head of the queue, it is currently being used for
// allocations; we skip it to avoid immediate thrashing.
if (page->prev == NULL)
return false;
// Calculate if the page's utilization is below the provided threshold.
return page->used <= (unsigned)(page->capacity * ratio);
}
return false;
}
Description
Long-running processes frequently encounter internal fragmentation over time, where numerous pages in a page queue remain underutilized. In extreme or synthetic cases, this fragmentation can lead to memory commitment levels 10x higher than actual usage.
Since mimalloc (or any other allocator) cannot compact memory without application-level cooperation, the Dragonfly project addresses this by triggering an asynchronous defragmentation process. btw, #1220 is related to how we recognize that the defragmentation should kick-off. Defragmentation task scans iteratively a pool of objects in each thread and reallocates them if their backing page's utilization falls below a specific threshold.
To facilitate this, we have patched mimalloc to include the function below. I suggest adding this (or a similar implementation) to the advanced heap API.