Skip to content

runtime: use process_madvise to batch scavenger memory releases on Linux #80389

Description

@Dorbmon

On Linux, Go's page scavenger calls sysUnused once for each candidate range selected by scavengeOne. This normally results in a separate madvise(MADV_FREE) or madvise(MADV_DONTNEED) syscall for each range.

Since Linux 6.13, process_madvise permits these advice values for the caller's own address space and accepts an iovec containing discontiguous ranges. Could the scavenger collect a small, bounded batch of candidate ranges and advise them with one process_madvise call, while retaining the existing per-range madvise path when the syscall or advice is unavailable or denied?

This could reduce syscall overhead on fragmented heaps. Linux 6.16 and later can additionally batch the associated TLB flushes across the vector.

An implementation would need to:

  • keep all selected ranges unavailable to allocation until the batch completes;
  • use PIDFD_SELF on Linux 6.15 and later, or a cached self pidfd on Linux 6.13–6.14;
  • detect support at runtime and preserve the existing fallback behavior;
  • use bounded batches to preserve scavenger pacing and stop points; and
  • handle short positive returns from process_madvise correctly.

I would like to prototype this and benchmark it directly against the current madvise path, using several batch sizes and both MADV_FREE and MADV_DONTNEED, if this direction seems reasonable.

Metadata

Metadata

Assignees

Labels

NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Performancecompiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Projects

Status
Todo

Relationships

None yet

Development

No branches or pull requests

Issue actions