memscope-rs 0.2.6

A memory tracking library for Rust applications.
Documentation
//! Complex Multi-Thread Memory Tracking Showcase
//!
//! This example demonstrates multi-thread memory tracking using the `start()` API.
use memscope_rs::{analyzer, MemScopeResult};
use std::thread;
use std::time::Instant;

fn main() -> MemScopeResult<()> {
    println!("Complex Multi-Thread Showcase - New API");
    println!("========================================\n");

    let num_threads = 8;
    let allocations_per_thread = 500;

    println!("Configuration:");
    println!("  Threads: {}", num_threads);
    println!("  Allocations per thread: {}", allocations_per_thread);

    let start_time = Instant::now();

    let guard = memscope_rs::start()?;
    println!("✓ Global tracking initialized\n");

    println!("Starting multi-threaded allocations...\n");

    let handles: Vec<_> = (0..num_threads)
        .map(|thread_id| {
            thread::spawn(move || {
                // Each spawned thread gets the global tracker (it's a singleton Arc)
                let t = memscope_rs::global_tracker().unwrap();
                for _i in 0..allocations_per_thread / 2 {
                    let data = vec![0i32; 64];
                    memscope_rs::track!(t, data);
                }

                for _i in 0..allocations_per_thread / 2 {
                    let data = vec![0i64; 256];
                    memscope_rs::track!(t, data);
                }

                println!(
                    "Thread {} completed {} allocations",
                    thread_id, allocations_per_thread
                );
            })
        })
        .collect();

    for handle in handles {
        handle.join().expect("Thread failed");
    }

    let duration = start_time.elapsed();
    let total_allocations = num_threads * allocations_per_thread;
    let throughput = total_allocations as f64 / duration.as_secs_f64();

    let stats = guard.get_stats();

    println!("\n========================================");
    println!("Memory Analysis Results:");
    println!("  Total allocations: {}", stats.total_allocations);
    println!("  Active allocations: {}", stats.active_allocations);
    println!(
        "  Peak memory: {} bytes ({:.2} MB)",
        stats.peak_memory_bytes,
        stats.peak_memory_bytes as f64 / 1024.0 / 1024.0
    );
    println!("  Duration: {:.2}ms", duration.as_secs_f64() * 1000.0);
    println!("  Throughput: {:.0} allocs/sec", throughput);

    // Use the unified Analyzer API
    println!("\n=== Unified Analyzer API ===\n");
    let mut az = analyzer(&guard)?;

    // Full analysis
    let report = az.analyze();
    println!("Analysis Report:");
    println!("  Allocations: {}", report.stats.allocation_count);
    println!("  Total Bytes: {}", report.stats.total_bytes);
    println!("  Peak Bytes: {}", report.stats.peak_bytes);

    // Leak detection
    let leaks = az.detect().leaks();
    println!("\nLeak Detection:");
    println!("  Leak Count: {}", leaks.leak_count);
    println!("  Leaked Bytes: {}", leaks.total_leaked_bytes);

    // Metrics
    let metrics = az.metrics().summary();
    println!("\nMetrics:");
    println!("  Types: {}", metrics.by_type.len());

    // No explicit export needed: MemScopeGuard's Drop triggers auto-export
    // to ./memscope-report/ on normal exit.

    Ok(())
}