memory-budget
Adaptive process-memory budgeting for applications with bounded caches.
memory-budget coordinates caches and other memory reporters under a target
resident-set size. It samples process RSS, applies a pluggable policy, and
adjusts registered cache ceilings. A Tokio task can drive the periodic ticks;
the policy itself is synchronous and deterministic, which keeps it easy to
test.
Core model
Resizableis the small contract implemented by an adjustable cache.NonCacheReporteraccounts for memory that cannot be resized by the budget.MemoryBudgetowns weak registrations, leases, RSS sampling, and ticks.Policydecides new cache ceilings from the latest bounded snapshot.RssSourceandJemallocStatsSourceisolate platform and allocator data.
The budget does not own cache entries, queue work, or payloads. It only coordinates the explicit byte measurements supplied by its participants.
Allocation reservations
Call try_lease(bytes) before allocating a payload. Outstanding leases
share one finite allowance equal to target_bytes; an oversized or competing
request returns ReservationError without changing the counter or allocating
a payload. Transfer the guard with ownership and drop it only after the owned
allocation is released. lease(bytes) uses the same accounting and panics on
refusal. It no longer permits overcommit. Zero-capacity budgets are invalid.
use ;
let budget = new;
let first = budget.try_lease.expect;
assert!;
drop;
assert!;
This enforces the sum of reservations, not a whole-process allocation cap. Unregistered allocations remain outside admission, and cache ceilings shrink on coordination ticks rather than synchronously at reservation time. The application must govern baseline, caches, copies, decoder expansion and native allocations before claiming a process memory bound. The optional abort ceiling remains a reactive safety mechanism.
observed_usage_bytes() samples memory without a coordination tick. It and
the tick use the maximum of OS process usage, jemalloc residency and live heap
allocation. These overlapping measurements must not be added, and a smaller
allocator reading must not hide other process memory.
Example
use Arc;
use ;
async
#
# ;
#
Environment configuration
BudgetConfig::from_env reads these variables:
| Variable | Meaning |
|---|---|
MEMORY_BUDGET_TARGET_MIB |
Soft RSS target; otherwise derived from system RAM |
MEMORY_BUDGET_TICK_SECS |
Tick interval, default 5 seconds |
MEMORY_BUDGET_HARD_CEILING_MIB |
Optional hard process ceiling |
Use BudgetConfig::new when configuration must be supplied explicitly.
Optional jemalloc support
Enable the jemalloc feature to expose SystemJemallocStats backed by
tikv-jemalloc-ctl. The heap-profiling feature adds threshold-driven
prof.dump diagnostics for applications built with jemalloc profiling.
These features are supported on Linux and macOS. Windows uses the default system-memory backend. CI tests default behavior on all three platforms and allocator features on their supported platforms, including a real allocator integration test. Keep the allocator and control crate requirements aligned when updating the native jemalloc family.
The minimum supported Rust version is 1.97.1. Main CI is the sole publisher; it validates the checkout and extracted archive before publication, then tests the actual public crate. Shared pipeline references are immutable and updated together by Dependabot.
License
Licensed under either of:
- Apache License, Version 2.0
- MIT License
at your option.