Bump allocation is a fast, but limited approach to allocation. We have a chunk of memory, and we maintain a pointer within that memory. Whenever we allocate an object, we do a quick test that we have enough capacity left in our chunk to allocate the object and then update the pointer by the object‘s size. *That’s it!*
The disadvantage of bump allocation is that there is no general way to deallocate individual objects or reclaim the memory region for a no-longer-in-use object.
These trade offs make bump allocation well-suited for phase-oriented allocations. That is, a group of objects that will all be allocated during the same program phase, used, and then can all be deallocated together as a group.
Drop
To deallocate all the objects in the arena at once, we can simply reset the bump pointer back to the start of the arena‘s memory chunk. This makes mass deallocation extremely fast, but allocated objects’ Drop
implementations are not invoked.
This implementation will allocate a new memory chunk from the global allocator and then start bump allocating into this new memory chunk.
use bumpalo::Bump; use std::u64; struct Doggo { cuteness: u64, age: u8, scritches_required: bool, } // Create a new arena to bump allocate into. let bump = Bump::new(); // Allocate values into the arena. let scooter = bump.alloc(Doggo { cuteness: u64::max_value(), age: 8, scritches_required: true, }); assert!(scooter.scritches_required);
When the "collections"
cargo feature is enabled, a fork of some of the std
library's collections are available in the collections
module. These collection types are modified to allocate their space inside bumpalo::Bump
arenas.
use bumpalo::{Bump, collections::Vec}; // Create a new bump arena. let bump = Bump::new(); // Create a vector of integers whose storage is backed by the bump arena. The // vector cannot outlive its backing arena, and this property is enforced with // Rust's lifetime rules. let mut v = Vec::new_in(&bump); // Push a bunch of integers onto `v`! for i in 0..100 { v.push(i); }
Eventually all std
collection types will be parameterized by an allocator and we can remove this collections
module and use the std
versions.
#![no_std]
SupportBumpalo is a no_std
crate. It depends only on the alloc
and core
crates.