madvise on Embedded Buffers: Verify Whether Discarding Memory Preserves the Data Contract
Use discard advice only when the application has explicitly surrendered the affected pages’ contents or can reconstruct them under the mapping’s contract. Linux MADV_DONTNEED can change what later reads return. A successful call is not a promise to preserve a live buffer while merely making its RAM accounting smaller.
This guide uses Linux man-pages 6.12 and ordinary userspace mappings. It compares private anonymous memory, shared file-backed memory and the narrower MADV_FREE operation. Device mappings, locked pages and huge pages require separate eligibility checks. One owned private anonymous page was tested on an x86-64 Linux 6.18.44 host; no memory-pressure workload or device mapping was exercised.
Start with a page-ownership ledger
Record the mapping origin, sharing mode, backing object, page size, active readers/writers and reconstruction source. A pointer and byte length are insufficient. An allocator can place several live objects in one page, so discarding a rounded range for one “unused” object can damage unrelated state that shares the page.
The madvise interface requires a page-aligned address and rounds the size upward to page boundaries. Before calling it, prove that the entire affected range belongs to the discardable allocation. Obtain the runtime page size and use checked range arithmetic; do not round outward into neighboring live buffers to satisfy alignment.
Quiesce all consumers before changing the content contract. A decoder, DMA submission or another process may still reference the data even when the owning thread has finished its immediate function. A reference count or ownership transfer must cover those readers; a convenient drop in one queue’s occupancy is not sufficient.

Choose the advice from the required next read
| Mapping and advice | Content contract to verify |
|---|---|
| Private anonymous plus MADV_DONTNEED | Later accesses obtain zero-fill-on-demand pages; previous private contents have been surrendered. |
| Shared file-backed plus MADV_DONTNEED | Later accesses use the current backing object’s contents; this is not an application rollback or durable-write operation. |
| Private anonymous plus MADV_FREE | Old contents may remain temporarily, but can disappear on reclamation; no continued-read preservation promise. |
| POSIX_MADV_DONTNEED | POSIX advice preserves access semantics; the documented glibc implementation treats this advice as a no-op. |
For shared mappings, MADV_DONTNEED need not immediately free the underlying pages. Other mappings or backing-object state still matter. Do not infer system-wide released memory from the calling process’s RSS alone, and do not use discard advice as a substitute for an explicit persistence protocol.
Private file-backed copy-on-write mappings deserve their own pinned implementation and content tests before admission. This article does not transfer anonymous zero-fill expectations to every mapping class. Keep unsupported combinations out of a generic “trim buffer” wrapper until their exact semantics are established.
Understand why MADV_FREE can hide a bug
MADV_FREE, available since Linux 4.5, applies only to private anonymous pages. The kernel may delay reclaiming them. A read shortly after the call can therefore observe the old bytes and make an incorrect preservation assumption look successful. Once reclaimed, later references see zero-filled pages.
A write to a page that was marked free but has not yet been reclaimed cancels that pending free operation for the page. This does not mean a later write reconstructs every old byte after reclamation. Treat the whole discarded payload as invalid and initialize the required contents before reuse, rather than restoring one field and trusting the rest.
The documentation notes an older boundary: before Linux 4.12, freeing these pages on a swapless system could happen immediately. This is another reason that a single observed retention result cannot establish a portable data contract. Pin the oldest supported kernel and mapping configuration in the test matrix.
Do not confuse Linux discard with POSIX advice
posix_madvise is specified as advice that does not change memory-access semantics. Its return convention is also different: it returns an error number directly rather than requiring the usual minus-one/errno interpretation. Check the exact API called by any portability wrapper.
The man-pages description states that glibc has treated POSIX_MADV_DONTNEED as a no-op since 2.6 because Linux MADV_DONTNEED has destructive semantics. Replacing one name with the other to improve a memory graph can therefore change correctness, not just performance. A wrapper should expose whether it provides a harmless hint or explicitly abandons data.
Keep device and backing-store operations outside the shortcut
MADV_DONTNEED is not permitted on locked pages or VM_PFNMAP areas under the documented contract. Many device mappings have special semantics outside ordinary managed anonymous memory. A successful test on malloc-like storage cannot qualify a memory-mapped device buffer.
HugeTLB support for MADV_DONTNEED was added in Linux 5.18 and uses the underlying huge-page alignment. Do not assume the base page size describes every mapping. Record actual mapping attributes and reject an unqualified range rather than retrying with broader alignment.
MADV_REMOVE is a different operation that can remove backing-store contents. It is not a more forceful synonym for a cache hint. Keep it out of this buffer-discard procedure; no backing-store removal operation was executed or recommended as a diagnostic default.
Use content assertions before memory statistics
An executed host fixture allocated one 4,096-byte private anonymous page, filled it with a known byte pattern, applied MADV_DONTNEED and read the entire page. Every byte was zero afterward. The fixture then unmapped its owned region. It demonstrates the host’s anonymous discard/refault behavior without claiming a target memory saving.
For a target qualification, test each approved mapping/advice pair with a full-page pattern, boundary pages and neighboring allocations protected by canaries. Confirm expected contents after refault and after reuse. For MADV_FREE, a test that observes retained bytes should be recorded as an allowed outcome, not a preservation guarantee; controlled reclaim tests belong in an isolated environment.
Only after content behavior is correct should you compare RSS, page faults and workload latency under the same observation window. A reduced resident set can trade memory for later faults, and a warm-cache test may miss that cost. The deliverable is a page-ownership and reconstruction contract backed by content assertions, with memory and latency results reported separately when actually measured.