Skip to content

proposal: Add mi_heap_page_is_underutilized to advanced heap API to combat internal fragmentation #1258

@romange

Description

@romange

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;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions