pub struct ArenaAllocator<A: Allocator> { /* private fields */ }Expand description
A block-based allocator that frees all memory at once.
ArenaAllocator<A> is generic over its backing allocator A which is
called for each individual block allocation and for every block
deallocation during reset.
The internal state uses Cell to allow shared (&self) allocation,
which is necessary so that multiple collections can borrow the same arena
simultaneously.
§Dropping
Dropping an ArenaAllocator automatically calls reset,
returning all memory to the backing allocator.
Implementations§
Source§impl<A: Allocator> ArenaAllocator<A>
impl<A: Allocator> ArenaAllocator<A>
Sourcepub fn new(backing: A) -> Self
pub fn new(backing: A) -> Self
Creates a new, empty arena backed by backing.
No memory is allocated from backing until the first call to
alloc.
Examples found in repository?
5fn main() {
6 let sys = SystemAllocator;
7 let arena = ArenaAllocator::new(&sys);
8
9 let mut numbers = ExVec::new(&arena);
10
11 for i in 1..=100 {
12 numbers.push(i);
13 }
14
15 println!("Sum: {}", numbers.iter().sum::<i32>());
16
17 arena.reset();
18 println!("Arena memory reclaimed. Allocations count was: {}", arena.alloc_count());
19}More examples
9fn main() {
10 let sys = CountingAllocator::new(SystemAllocator);
11
12 println!("=== ExBox & SystemAllocator ===");
13 {
14 let b = ExBox::new(42, &sys).expect("Failed to alloc Box");
15 println!("Box value: {}", *b);
16 }
17
18 let stats = sys.stats();
19 println!("Allocated: {} bytes", stats.bytes_allocated);
20 println!("Deallocated: {} bytes", stats.bytes_freed);
21 println!("Live bytes: {}\n", stats.bytes_live);
22
23 println!("=== ExVec & Arena (Linear Allocation) ===");
24 {
25 let arena = ArenaAllocator::new(&sys);
26
27 let mut v = ExVec::new(&arena);
28 for i in 0..5 {
29 v.push(i * 10);
30 }
31 println!("Vec: {:?}", v.as_slice());
32
33 arena.reset();
34 println!("Arena reset performed");
35 }
36
37 println!("\n=== ExString & Pool (Fixed Size Blocks) ===");
38 {
39 let pool = PoolAllocator::typed::<[u8; 64]>(&sys, 10)
40 .expect("Failed to create Pool");
41
42 let mut s = ExString::new(&pool);
43 s.push_str("Hello from ZigZag!");
44
45 println!("String in Pool: {}", s.as_str());
46 println!("Pool free slots: {}", pool.free_count());
47 }
48
49 println!("\n=== Final Global Stats ===");
50 let final_stats = sys.stats();
51 println!("Total count of alloc() calls: {}", final_stats.allocs);
52 println!("Total count of dealloc() calls: {}", final_stats.deallocs);
53 println!("Total bytes allocated: {}", final_stats.bytes_allocated);
54 println!("Total bytes freed: {}", final_stats.bytes_freed);
55 println!("Current leak/live size: {} bytes", final_stats.bytes_live);
56}Sourcepub fn alloc_count(&self) -> usize
pub fn alloc_count(&self) -> usize
Returns the number of live allocations currently managed by this arena.
The counter is reset to zero by reset or
reset_zeroed.
Examples found in repository?
5fn main() {
6 let sys = SystemAllocator;
7 let arena = ArenaAllocator::new(&sys);
8
9 let mut numbers = ExVec::new(&arena);
10
11 for i in 1..=100 {
12 numbers.push(i);
13 }
14
15 println!("Sum: {}", numbers.iter().sum::<i32>());
16
17 arena.reset();
18 println!("Arena memory reclaimed. Allocations count was: {}", arena.alloc_count());
19}Sourcepub fn reset(&self)
pub fn reset(&self)
Releases all memory blocks managed by this arena back to the backing allocator.
After this call, all pointers previously returned by
alloc are invalid.
§Safety
The caller must ensure that no pointers previously obtained from
this arena are used after reset returns (use-after-free).
Examples found in repository?
5fn main() {
6 let sys = SystemAllocator;
7 let arena = ArenaAllocator::new(&sys);
8
9 let mut numbers = ExVec::new(&arena);
10
11 for i in 1..=100 {
12 numbers.push(i);
13 }
14
15 println!("Sum: {}", numbers.iter().sum::<i32>());
16
17 arena.reset();
18 println!("Arena memory reclaimed. Allocations count was: {}", arena.alloc_count());
19}More examples
9fn main() {
10 let sys = CountingAllocator::new(SystemAllocator);
11
12 println!("=== ExBox & SystemAllocator ===");
13 {
14 let b = ExBox::new(42, &sys).expect("Failed to alloc Box");
15 println!("Box value: {}", *b);
16 }
17
18 let stats = sys.stats();
19 println!("Allocated: {} bytes", stats.bytes_allocated);
20 println!("Deallocated: {} bytes", stats.bytes_freed);
21 println!("Live bytes: {}\n", stats.bytes_live);
22
23 println!("=== ExVec & Arena (Linear Allocation) ===");
24 {
25 let arena = ArenaAllocator::new(&sys);
26
27 let mut v = ExVec::new(&arena);
28 for i in 0..5 {
29 v.push(i * 10);
30 }
31 println!("Vec: {:?}", v.as_slice());
32
33 arena.reset();
34 println!("Arena reset performed");
35 }
36
37 println!("\n=== ExString & Pool (Fixed Size Blocks) ===");
38 {
39 let pool = PoolAllocator::typed::<[u8; 64]>(&sys, 10)
40 .expect("Failed to create Pool");
41
42 let mut s = ExString::new(&pool);
43 s.push_str("Hello from ZigZag!");
44
45 println!("String in Pool: {}", s.as_str());
46 println!("Pool free slots: {}", pool.free_count());
47 }
48
49 println!("\n=== Final Global Stats ===");
50 let final_stats = sys.stats();
51 println!("Total count of alloc() calls: {}", final_stats.allocs);
52 println!("Total count of dealloc() calls: {}", final_stats.deallocs);
53 println!("Total bytes allocated: {}", final_stats.bytes_allocated);
54 println!("Total bytes freed: {}", final_stats.bytes_freed);
55 println!("Current leak/live size: {} bytes", final_stats.bytes_live);
56}Sourcepub fn reset_zeroed(&self)
pub fn reset_zeroed(&self)
Trait Implementations§
Source§impl<A: Allocator> Allocator for ArenaAllocator<A>
impl<A: Allocator> Allocator for ArenaAllocator<A>
Source§unsafe fn alloc(&self, layout: Layout) -> Option<NonNull<u8>>
unsafe fn alloc(&self, layout: Layout) -> Option<NonNull<u8>>
Allocates a new block, prepends a [Header], and returns a pointer to
the user-data region.
Internally calls the backing allocator for a single block large enough
to hold both the Header and the user data (with proper alignment
padding in between), then links the new block at the head of the
internal list.
§Safety
layout.size()must be greater than zero.- The returned pointer is valid until the next call to
resetor until the arena is dropped.
Source§impl<A: Allocator> ArenaExt for ArenaAllocator<A>
impl<A: Allocator> ArenaExt for ArenaAllocator<A>
Source§unsafe fn alloc_zeroed(&self, layout: Layout) -> Option<NonNull<u8>>
unsafe fn alloc_zeroed(&self, layout: Layout) -> Option<NonNull<u8>>
Allocates a block and zero-fills the user-data region with SIMD.
Delegates to alloc and then applies a SIMD
zero-fill, which is faster than a scalar loop for large allocations.
§Safety
layout.size()must be greater than zero.- The returned pointer becomes invalid after
resetor when the arena is dropped.