pub struct CountingAllocator<A: Allocator> { /* private fields */ }Expand description
An Allocator wrapper that records allocation and deallocation statistics.
Wrap any existing allocator with CountingAllocator::new(inner) to
transparently instrument it. Statistics can be queried at any time via
stats and reset via reset_stats.
§Thread Safety
CountingAllocator uses Cell internally, which is not Sync.
It is suitable for single-threaded use only. For multi-threaded scenarios,
wrap an atomic-based allocator instead.
Implementations§
Source§impl<A: Allocator> CountingAllocator<A>
impl<A: Allocator> CountingAllocator<A>
Sourcepub fn new(inner: A) -> Self
pub fn new(inner: A) -> Self
Creates a new CountingAllocator wrapping inner.
All counters start at zero.
Examples found in repository?
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 stats(&self) -> AllocStats
pub fn stats(&self) -> AllocStats
Returns a snapshot of all statistics.
Counters are cumulative since the last call to
reset_stats.
§Example
let counting = CountingAllocator::new(SystemAllocator);
let _ = unsafe { counting.alloc(Layout::new::<u64>()) };
let stats = counting.stats();
assert_eq!(stats.allocs, 1);
assert_eq!(stats.bytes_allocated, 8);Examples found in repository?
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_stats(&self)
pub fn reset_stats(&self)
Resets all counters to zero.
Does not affect the underlying allocator or any live allocations.
Trait Implementations§
Source§impl<A: Allocator> Allocator for CountingAllocator<A>
impl<A: Allocator> Allocator for CountingAllocator<A>
Source§unsafe fn dealloc(&self, ptr: NonNull<u8>, layout: Layout)
unsafe fn dealloc(&self, ptr: NonNull<u8>, layout: Layout)
Forwards the deallocation to the inner allocator and records statistics.
§Safety
Inherits all safety requirements from A::dealloc.
In particular, ptr must have been obtained from this allocator (and
therefore from its inner allocator).