Small, lazy commit, fixed-capacity arena allocator for single-threaded Rust programs.
You pick the capacity up front. The arena capacity never grows.
Raw bump allocations stay stable. When the arena is full, fallible allocation
returns None.
| Type | What it gives you | Drop behavior |
|---|---|---|
BumpArena |
Raw byte allocation from reserved virtual memory | Values must be dropped by the caller |
TypedArena<'a, T, A = BumpArena> |
Values of one type from a backing allocator | Drops live values in reverse allocation order |
nightlyrequires a nightly Rust toolchain and enables the unstable standard-libraryallocator_apiimplementation forBumpArena. Typed arenas backed byBumpArenaalso use that allocator for their internal tracking storage. The allocator implementation remains fixed-capacity, butgrow,grow_zeroed, andshrinkcan relocate blocks into remaining arena capacity when in-place resizing is not possible, so allocator-managed blocks must use the pointer returned from successful resize operations.
Both arenas expose try_* for fallible allocation and alloc / alloc_* for the
panicking variant. The 2.0 API intentionally keeps only BumpArena and
TypedArena, the old lazy/ref arena names were removed.
BumpArena gives you uninitialized bytes. You choose the layout, initialize
the memory, and drop any values you place there.
use core::alloc::Layout;
use linalloc::BumpArena;
let arena = BumpArena::new(128);
let slot = arena.try_alloc_uninit(Layout::new::<u64>()).unwrap();
let ptr = slot.as_mut_ptr().cast::<u64>();
unsafe { ptr.write(42) };
assert_eq!(unsafe { *ptr }, 42);Enable nightly when you want bump arena to back standard-library
collections that use the unstable allocator API:
[dependencies]
linalloc = { version = "2", features = ["nightly"] }#![feature(allocator_api)]
# #[cfg(feature = "nightly")]
# {
use linalloc::BumpArena;
let arena = BumpArena::new(128);
let mut values = Vec::with_capacity_in(1, &arena);
values.push(1);
values.try_reserve(1).unwrap();
values.push(2);
assert_eq!(&values, &[1, 2]);
# }TypedArena<'a, T, A = BumpArena> stores initialized T values in a backing allocator
A that implements the UninitAllocator trait
and drops the live values when the arena is reset or dropped.
use linalloc::{BumpArena, TypedArena};
let bump = BumpArena::new(128); // Implements `UninitAllocator`
let mut foo_arena = TypedArena::<String>::new_in(&bump);
let mut bar_arena = TypedArena::<String>::new_in(&bump);
let foo = foo_arena.try_alloc("foo".to_owned()).unwrap();
let bar = bar_arena.try_alloc("bar".to_owned()).unwrap();
assert_eq!(foo, "foo");
assert_eq!(bar, "bar");Bump arena keeps the raw OS code from the last failed reserve or commit call.
Use it when try_new fails, or when allocation returns None and you need to
know whether the OS refused more committed memory.
use core::alloc::Layout;
use linalloc::BumpArena;
if let Err(code) = BumpArena::try_new(usize::MAX) {
assert_eq!(Some(code), std::io::Error::last_os_error().raw_os_error());
}
let arena = BumpArena::new(128);
let _slot = arena.try_alloc_uninit(Layout::new::<u64>()).unwrap();
assert_eq!(arena.last_os_error_code(), None);Bump arenas hand you uninitialized bytes. Do not read them until you have written them. Values stored in bump arenas are not dropped automatically.
Typed arenas own initialized values. reset takes &mut self, drops live
values in reverse allocation order, and clears the typed arena’s tracking. It
does not rewind the backing allocator; reuse is governed by that allocator’s
own reset/drop lifecycle.
For bump arenas, reset is unsafe. All returned slices must be dead, and
any values stored in the arena must already have been dropped.
With nightly, BumpArena implements
core::alloc::Allocator. Per-block deallocate is a no-op -- memory is reclaimed
only by reset or by dropping the arena. grow, grow_zeroed, and shrink
reuse the existing block when possible and otherwise may relocate it into
remaining arena capacity. Relocated old blocks are logically deallocated but
their bytes are not physically reclaimed until reset or drop. Drop all
collections and values that use an arena allocator before calling reset.