pub struct ModAlloc { /* private fields */ }Expand description
Global allocator wrapper that tracks allocations.
Install as #[global_allocator] to enable tracking. The wrapper
forwards every allocation, deallocation, reallocation, and
zero-initialised allocation to std::alloc::System and records
the event in four lock-free AtomicU64 counters.
§Example
use mod_alloc::ModAlloc;
#[global_allocator]
static GLOBAL: ModAlloc = ModAlloc::new();
fn main() {
let v: Vec<u8> = vec![0; 1024];
let stats = GLOBAL.snapshot();
assert!(stats.alloc_count >= 1);
drop(v);
}Implementations§
Source§impl ModAlloc
impl ModAlloc
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Construct a new ModAlloc allocator wrapper.
All counters start at zero. This function is const, which
allows construction in a static for use as
#[global_allocator].
§Example
use mod_alloc::ModAlloc;
static GLOBAL: ModAlloc = ModAlloc::new();
let stats = GLOBAL.snapshot();
assert_eq!(stats.alloc_count, 0);Examples found in repository?
More examples
Sourcepub fn snapshot(&self) -> AllocStats
pub fn snapshot(&self) -> AllocStats
Snapshot the current counter values.
Each counter is read independently with Relaxed ordering;
the resulting AllocStats is a coherent best-effort view
but does not represent a single atomic moment in time. For
scoped measurement, prefer Profiler.
§Example
use mod_alloc::ModAlloc;
let alloc = ModAlloc::new();
let stats = alloc.snapshot();
assert_eq!(stats.alloc_count, 0);Examples found in repository?
26fn main() {
27 for _ in 0..WARMUP {
28 let v: Vec<u8> = Vec::with_capacity(SIZE);
29 std::hint::black_box(&v);
30 }
31
32 GLOBAL.reset();
33 let start = Instant::now();
34 for _ in 0..N {
35 let v: Vec<u8> = Vec::with_capacity(SIZE);
36 std::hint::black_box(&v);
37 }
38 let elapsed = start.elapsed();
39
40 let snap = GLOBAL.snapshot();
41 let per_cycle_ns = elapsed.as_nanos() as f64 / N as f64;
42
43 println!("bench_overhead:");
44 println!(" iterations: {N}");
45 println!(" allocation size: {SIZE} bytes");
46 println!(" elapsed: {elapsed:?}");
47 println!(" per alloc+dealloc: {per_cycle_ns:.1} ns");
48 println!();
49 println!("counter snapshot after run:");
50 println!(" alloc_count: {}", snap.alloc_count);
51 println!(" total_bytes: {}", snap.total_bytes);
52 println!(" current_bytes: {}", snap.current_bytes);
53 println!(" peak_bytes: {}", snap.peak_bytes);
54}More examples
10fn main() {
11 let p = Profiler::start();
12
13 let v: Vec<u64> = (0..1_000).collect();
14 let sum: u64 = v.iter().sum();
15 drop(v);
16
17 let mut owned: Vec<String> = Vec::with_capacity(100);
18 for i in 0..100 {
19 owned.push(format!("item-{i}"));
20 }
21 drop(owned);
22
23 let delta = p.stop();
24 println!("Profiler delta (alloc/total/current = delta; peak = absolute):");
25 println!(" alloc_count: {}", delta.alloc_count);
26 println!(" total_bytes: {}", delta.total_bytes);
27 println!(" current_bytes: {}", delta.current_bytes);
28 println!(" peak_bytes: {}", delta.peak_bytes);
29
30 let snap = GLOBAL.snapshot();
31 println!();
32 println!("Process-wide snapshot:");
33 println!(" alloc_count: {}", snap.alloc_count);
34 println!(" total_bytes: {}", snap.total_bytes);
35 println!(" current_bytes: {}", snap.current_bytes);
36 println!(" peak_bytes: {}", snap.peak_bytes);
37
38 println!();
39 println!("(workload checksum: {sum})");
40}Sourcepub fn reset(&self)
pub fn reset(&self)
Reset all counters to zero.
Intended for use at the start of a profile run, before any
outstanding allocations exist. Calling reset while
allocations are live can cause current_bytes to wrap on
subsequent deallocations; the other counters are unaffected.
§Example
use mod_alloc::ModAlloc;
let alloc = ModAlloc::new();
alloc.reset();
let stats = alloc.snapshot();
assert_eq!(stats.alloc_count, 0);Examples found in repository?
26fn main() {
27 for _ in 0..WARMUP {
28 let v: Vec<u8> = Vec::with_capacity(SIZE);
29 std::hint::black_box(&v);
30 }
31
32 GLOBAL.reset();
33 let start = Instant::now();
34 for _ in 0..N {
35 let v: Vec<u8> = Vec::with_capacity(SIZE);
36 std::hint::black_box(&v);
37 }
38 let elapsed = start.elapsed();
39
40 let snap = GLOBAL.snapshot();
41 let per_cycle_ns = elapsed.as_nanos() as f64 / N as f64;
42
43 println!("bench_overhead:");
44 println!(" iterations: {N}");
45 println!(" allocation size: {SIZE} bytes");
46 println!(" elapsed: {elapsed:?}");
47 println!(" per alloc+dealloc: {per_cycle_ns:.1} ns");
48 println!();
49 println!("counter snapshot after run:");
50 println!(" alloc_count: {}", snap.alloc_count);
51 println!(" total_bytes: {}", snap.total_bytes);
52 println!(" current_bytes: {}", snap.current_bytes);
53 println!(" peak_bytes: {}", snap.peak_bytes);
54}Trait Implementations§
Source§impl GlobalAlloc for ModAlloc
impl GlobalAlloc for ModAlloc
Source§unsafe fn alloc(&self, layout: Layout) -> *mut u8
unsafe fn alloc(&self, layout: Layout) -> *mut u8
layout. Read moreSource§unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8
alloc, but also ensures that the contents
are set to zero before being returned. Read more