This repository was archived by the owner on Jun 2, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
This repository was archived by the owner on Jun 2, 2025. It is now read-only.
Implement two-phase purging #521
Copy link
Copy link
Closed
Description
The current purging implementation uses an equivalent of either MADV_FREE (lazy, maybe later) or MADV_DONTNEED (forced, now), with a preference for the cheaper MADV_FREE. Unfortunately, lazy purging obscures system-level statistics regarding resident memory (RSS -- resident set size), because purged pages continue to be counted as resident unless memory pressure causes them to be repurposed. We can benefit from the low overhead of lazy purging, yet quiesce to the expected RSS, if we use both lazy and forced purging, driven by fast and slow decay curves, respectively.
Overview of necessary changes:
- This requires an additional memory state in addition to "clean" and "dirty" called, say, "muzzy". This tri-state needs to be supported by
extent_t, so that separate FIFO queues can be maintained for dirty vs muzzy extents, and the extents can self-identify which queue they are part of. - The two separate decay schedules can easily be driven by two
arena_decay_tfields embedded inarena_t. - Several mallctl API changes are necessary:
- Split
opt.decay_timeintoopt.decay_{lazy,forced}_time. - Split
arena.<i>.decayintoarena.<i>.decay_{lazy,forced}. - Split
arenas.decay_timeintoarenas.decay_{lazy,forced}_time. - Split
stats.arenas.<i>.decay_timeintostats.arenas.<i>.decay_{lazy,forced}_time.
- Split
- The
extent_purge_thook needs an additionalbool forcedparameter, and callers need to be prepared for the hook to support neither, one, or both of the purge modes. In particular, Linux prior to 4.5 does not support lazy purging, and Windows only supports forced purging via (racy/fragile) decommit+recommit, which is pointless since we already have separate decommit machinery.