#[cfg(not(feature = "memory_management"))]
#[allow(dead_code)]
fn main() {
println!("This example requires the 'memory_management' feature to be enabled.");
println!("Run with: cargo run --example enhanced_memory_metrics_example --features memory_management");
}
#[cfg(feature = "memory_management")]
use chrono::Utc;
#[cfg(feature = "memory_management")]
use scirs2_core::memory::metrics::{
LeakDetectionConfig, MemoryAnalytics, MemoryEvent, MemoryEventType, MemoryProfiler,
MemoryProfilerConfig, RiskAssessment,
};
#[cfg(feature = "memory_management")]
use std::thread;
#[cfg(feature = "memory_management")]
use std::time::{Duration, Instant};
#[cfg(feature = "memory_management")]
#[allow(dead_code)]
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Enhanced Memory Metrics System Demonstration ===");
demo_memory_analytics()?;
demo_leak_detection()?;
demo_memory_profiler()?;
demo_pattern_analysis()?;
demo_performance_analysis()?;
println!("\n=== Enhanced Memory Metrics Demo Complete ===");
Ok(())
}
#[cfg(feature = "memory_management")]
#[allow(dead_code)]
fn demo_memory_analytics() -> Result<(), Box<dyn std::error::Error>> {
println!("\n1. Basic Memory Analytics");
println!("=========================");
let mut analytics = MemoryAnalytics::new(LeakDetectionConfig::default());
let components = ["DataProcessor", "NetworkClient", "Cache"];
let mut addresses = [0x1000, 0x2000, 0x3000];
println!("Simulating memory allocation patterns...");
for i in 0..50 {
for (idx, component) in components.iter().enumerate() {
let size = 1024 + (i * 100) + (idx * 512);
let address = addresses[idx];
let event = MemoryEvent::new(MemoryEventType::Allocation, *component, size, address);
analytics.record_event(event);
addresses[idx] += size;
if i % 10 == 0 && i > 0 {
let dealloc_size = size / 2;
let dealloc_event = MemoryEvent::new(
MemoryEventType::Deallocation,
*component,
dealloc_size,
address,
);
analytics.record_event(dealloc_event);
}
}
thread::sleep(Duration::from_millis(10));
}
for component in &components {
if let Some(analysis) = analytics.analyze_patterns(component) {
println!("\nAnalysis for {}:", component);
println!(" Patterns detected: {}", analysis.patterns.len());
println!(
" Allocation frequency: {:.2}/sec",
analysis.efficiency.allocation_frequency
);
println!(
" Memory reuse ratio: {:.2}",
analysis.efficiency.reuse_ratio
);
println!(
" Fragmentation estimate: {:.2}",
analysis.efficiency.fragmentation_estimate
);
println!(" Issues found: {}", analysis.potential_issues.len());
println!(" Recommendations: {}", analysis.recommendations.len());
for (i, recommendation) in analysis.recommendations.iter().enumerate() {
match recommendation {
scirs2_core::memory::metrics::OptimizationRecommendation::UseBufferPooling { expected_savings, .. } => {
println!(" {}. Use buffer pooling (saves ~{} bytes)", i + 1, expected_savings);
}
scirs2_core::memory::metrics::OptimizationRecommendation::BatchAllocations { suggested_batch_size, .. } => {
println!(" {}. Batch allocations (batch size: {})", i + 1, suggested_batch_size);
}
scirs2_core::memory::metrics::OptimizationRecommendation::PreAllocateMemory { suggested_size, .. } => {
println!(" {}. Pre-allocate {} bytes", i + 1, suggested_size);
}
_ => {
println!(" {}. Other optimization available", i + 1);
}
}
}
}
}
Ok(())
}
#[cfg(feature = "memory_management")]
#[allow(dead_code)]
fn demo_leak_detection() -> Result<(), Box<dyn std::error::Error>> {
println!("\n2. Memory Leak Detection");
println!("========================");
let mut analytics = MemoryAnalytics::new(LeakDetectionConfig {
leak_threshold_bytes: 1024, leak_threshold_duration: Duration::from_secs(1),
growth_rate_threshold: 500.0, ..Default::default()
});
println!("Simulating memory leak in 'LeakyComponent'...");
let mut address = 0x10000;
for i in 0..30 {
let size = 1000 + (i * 50);
let event = MemoryEvent::new(MemoryEventType::Allocation, "LeakyComponent", size, address);
analytics.record_event(event);
address += size;
thread::sleep(Duration::from_millis(100));
}
println!("Simulating healthy component 'HealthyComponent'...");
let mut healthy_address = 0x20000;
for i in 0..30 {
let size = 1000;
let alloc_event = MemoryEvent::new(
MemoryEventType::Allocation,
"HealthyComponent",
size,
healthy_address,
);
analytics.record_event(alloc_event);
if i > 5 {
let dealloc_event = MemoryEvent::new(
MemoryEventType::Deallocation,
"HealthyComponent",
size,
healthy_address - (5 * size),
);
analytics.record_event(dealloc_event);
}
healthy_address += size;
thread::sleep(Duration::from_millis(100));
}
let leak_results = analytics.get_leak_detection_results();
println!("\nLeak Detection Results:");
for result in leak_results {
println!("\nComponent: {}", result.component);
println!(" Leak detected: {}", result.leak_detected);
println!(" Growth rate: {:.2} bytes/sec", result.growth_rate);
println!(" Confidence: {:.2}", result.confidence);
println!(" Current usage: {} bytes", result.current_usage);
if result.leak_detected {
println!(" 🚨 LEAK ALERT! 🚨");
println!(
" Projected usage in 1 hour: {} bytes",
result.projected_usage_1h
);
println!(
" Projected usage in 24 hours: {} bytes",
result.projected_usage_24h
);
} else {
println!(" ✅ No leak detected");
}
}
Ok(())
}
#[cfg(feature = "memory_management")]
#[allow(dead_code)]
fn demo_memory_profiler() -> Result<(), Box<dyn std::error::Error>> {
println!("\n3. Memory Profiler with Real-time Monitoring");
println!("===========================================");
let config = MemoryProfilerConfig {
enabled: true,
profiling_interval: Duration::from_secs(2),
auto_leak_detection: true,
auto_recommendations: true,
save_to_file: false,
..Default::default()
};
let profiler = MemoryProfiler::new(config);
let sessionid =
profiler.start_session(Some(format!("demo_session_{}", Utc::now().timestamp())));
println!("Started profiling session: {}", sessionid);
println!("Simulating memory operations...");
let components = ["WebServer", "Database", "Cache", "Logger"];
let mut addresses: Vec<usize> = (0..components.len())
.map(|i| 0x10000 + (i * 0x10000))
.collect();
for iteration in 0..20 {
for (idx, component) in components.iter().enumerate() {
let size = match *component {
"WebServer" => 2048 + (iteration * 100), "Database" => 8192, "Cache" => {
if iteration % 3 == 0 {
16384
} else {
0
}
} "Logger" => 512 + (iteration * iteration * 10), _ => 1024,
};
if size > 0 {
let event = MemoryEvent::new(
MemoryEventType::Allocation,
*component,
size,
addresses[idx],
);
profiler.record_event(event);
addresses[idx] += size;
}
if iteration % 5 == 0 && iteration > 0 {
let dealloc_size = size / 2;
if dealloc_size > 0 {
let dealloc_event = MemoryEvent::new(
MemoryEventType::Deallocation,
*component,
dealloc_size,
addresses[idx] - size,
);
profiler.record_event(dealloc_event);
}
}
}
if iteration % 5 == 0 {
let health = profiler.health_check();
println!(
"Health check at iteration {}: Score {:.2}",
iteration, health.health_score
);
match health.risk_assessment {
RiskAssessment::Low => println!(" Status: 🟢 Low risk"),
RiskAssessment::Medium { ref issues } => {
println!(" Status: 🟡 Medium risk ({} issues)", issues.len());
}
RiskAssessment::High {
ref critical_issues,
} => {
println!(
" Status: 🔴 High risk ({} critical issues)",
critical_issues.len()
);
}
}
}
thread::sleep(Duration::from_millis(200));
}
println!("\nEnding profiling session...");
if let Some(result) = profiler.end_session() {
println!("\nProfiling Results:");
println!("==================");
println!("Session ID: {}", result.session.id);
println!("Duration: {} micros", result.session.duration_micros);
println!("Events recorded: {}", result.session.event_count);
println!("Components tracked: {}", result.session.component_count);
println!(
"Peak memory usage: {} bytes ({:.2} MB)",
result.session.peak_memory_usage,
result.session.peak_memory_usage as f64 / (1024.0 * 1024.0)
);
println!("Leaks detected: {}", result.session.leaks_detected);
println!("\nPerformance Impact:");
println!(
" Total allocation time: {:?}",
result.performance_impact.total_allocation_time
);
println!(
" Performance bottlenecks: {}",
result.performance_impact.performance_bottlenecks
);
println!(
" Memory bandwidth utilization: {:.2}%",
result.performance_impact.memorybandwidth_utilization * 100.0
);
println!("\nSummary:");
println!(" Health score: {:.2}/1.0", result.summary.health_score);
println!(" Key insights: {}", result.summary.key_insights.len());
for insight in &result.summary.key_insights {
println!(" • {}", insight);
}
println!(
" Priority recommendations: {}",
result.summary.priority_recommendations.len()
);
for recommendation in &result.summary.priority_recommendations {
println!(" • {}", recommendation);
}
}
Ok(())
}
#[cfg(feature = "memory_management")]
#[allow(dead_code)]
fn demo_pattern_analysis() -> Result<(), Box<dyn std::error::Error>> {
println!("\n4. Pattern Analysis and Optimization Recommendations");
println!("===================================================");
let mut analytics = MemoryAnalytics::new(LeakDetectionConfig::default());
println!("Simulating various allocation patterns...");
println!(" Simulating burst allocation pattern...");
for burst in 0..3 {
for i in 0..10 {
let size = 16384; let event = MemoryEvent::new(
MemoryEventType::Allocation,
"BatchProcessor",
size,
0x100000 + (burst * 200000) + (i * size),
);
analytics.record_event(event);
thread::sleep(Duration::from_millis(20));
}
thread::sleep(Duration::from_millis(500));
for i in 0..5 {
let event = MemoryEvent::new(
MemoryEventType::Deallocation,
"BatchProcessor",
16384,
0x100000 + (burst * 200000) + (i * 16384),
);
analytics.record_event(event);
thread::sleep(Duration::from_millis(10));
}
}
println!(" Simulating periodic allocation cycles...");
for cycle in 0..5 {
for i in 0..8 {
let size = 4096 + (i * 512);
let event = MemoryEvent::new(
MemoryEventType::Allocation,
"ManagedHeap",
size,
0x200000 + (cycle * 100000) + (i * size),
);
analytics.record_event(event);
thread::sleep(Duration::from_millis(50));
}
for i in 0..6 {
let size = 4096 + (i * 512);
let event = MemoryEvent::new(
MemoryEventType::Deallocation,
"ManagedHeap",
size,
0x200000 + (cycle * 100000) + (i * size),
);
analytics.record_event(event);
thread::sleep(Duration::from_millis(25));
}
}
println!(" Simulating steady growth pattern...");
for i in 0..30 {
let size = 2048 + (i * 64); let event = MemoryEvent::new(
MemoryEventType::Allocation,
"GrowingCache",
size,
0x300000 + (i * size),
);
analytics.record_event(event);
thread::sleep(Duration::from_millis(100));
}
let components = ["BatchProcessor", "ManagedHeap", "GrowingCache"];
for component in &components {
if let Some(analysis) = analytics.analyze_patterns(component) {
println!("\n📊 Pattern Analysis for {}:", component);
println!(" Detected Patterns:");
for (i, pattern) in analysis.patterns.iter().enumerate() {
match pattern {
scirs2_core::memory::metrics::AllocationPattern::SteadyGrowth {
rate,
confidence,
} => {
println!(
" {}. Steady Growth: {:.2} bytes/sec (confidence: {:.2})",
i + 1,
rate,
confidence
);
}
scirs2_core::memory::metrics::AllocationPattern::PeriodicCycle {
cycle_duration,
peak_size,
confidence,
} => {
println!(" {}. Periodic Cycle: {:?} cycles, peak {} bytes (confidence: {:.2})",
i + 1, cycle_duration, peak_size, confidence);
}
scirs2_core::memory::metrics::AllocationPattern::BurstAllocation {
burst_size,
burst_duration,
confidence,
} => {
println!(
" {}. Burst Allocation: {} bytes in {:?} (confidence: {:.2})",
i + 1,
burst_size,
burst_duration,
confidence
);
}
scirs2_core::memory::metrics::AllocationPattern::Plateau {
size,
duration,
confidence,
} => {
println!(
" {}. Plateau: {} bytes for {:?} (confidence: {:.2})",
i + 1,
size,
duration,
confidence
);
}
}
}
println!(" Efficiency Metrics:");
println!(" Reuse ratio: {:.2}", analysis.efficiency.reuse_ratio);
println!(
" Allocation frequency: {:.2}/sec",
analysis.efficiency.allocation_frequency
);
println!(
" Avg allocation lifetime: {:?}",
analysis.efficiency.avg_allocation_lifetime
);
println!(
" Fragmentation estimate: {:.2}",
analysis.efficiency.fragmentation_estimate
);
if !analysis.potential_issues.is_empty() {
println!(" 🚨 Potential Issues:");
for (i, issue) in analysis.potential_issues.iter().enumerate() {
match issue {
scirs2_core::memory::metrics::MemoryIssue::MemoryLeak {
growth_rate,
duration,
severity,
} => {
println!(" {}. Memory Leak: {:.2} bytes/sec growth over {:?} (severity: {:.2})",
i + 1, growth_rate, duration, severity);
}
scirs2_core::memory::metrics::MemoryIssue::HighAllocationFrequency {
frequency,
impact,
} => {
println!(
" {}. High Allocation Frequency: {:.2}/sec - {}",
i + 1,
frequency,
impact
);
}
scirs2_core::memory::metrics::MemoryIssue::HighPeakUsage {
peak_size,
..
} => {
println!(
" {}. High Peak Usage: {} bytes ({:.2} MB)",
i + 1,
peak_size,
*peak_size as f64 / (1024.0 * 1024.0)
);
}
scirs2_core::memory::metrics::MemoryIssue::MemoryFragmentation {
fragmentation_ratio,
potential_waste,
} => {
println!(" {}. Memory Fragmentation: {:.2} ratio, {} bytes potential waste",
i + 1, fragmentation_ratio, potential_waste);
}
scirs2_core::memory::metrics::MemoryIssue::IneffientBufferPool {
efficiency,
pool_misses,
} => {
println!(
" {}. Inefficient Buffer Pool: {:.2} efficiency, {} misses",
i + 1,
efficiency,
pool_misses
);
}
}
}
}
if !analysis.recommendations.is_empty() {
println!(" 💡 Optimization Recommendations:");
for (i, recommendation) in analysis.recommendations.iter().enumerate() {
match recommendation {
scirs2_core::memory::metrics::OptimizationRecommendation::UseBufferPooling { expected_savings, suggested_poolsizes } => {
println!(" {}. Use Buffer Pooling: Save ~{} bytes, pools: {:?}",
i + 1, expected_savings, suggested_poolsizes);
}
scirs2_core::memory::metrics::OptimizationRecommendation::BatchAllocations { current_frequency, suggested_batch_size } => {
println!(" {}. Batch Allocations: Reduce from {:.2}/sec, batch size: {}",
i + 1, current_frequency, suggested_batch_size);
}
scirs2_core::memory::metrics::OptimizationRecommendation::PreAllocateMemory { suggested_size, performance_gain } => {
println!(" {}. Pre-allocate {} bytes: {}",
i + 1, suggested_size, performance_gain);
}
scirs2_core::memory::metrics::OptimizationRecommendation::UseMemoryEfficientStructures { current_type, suggested_alternative, memory_reduction } => {
println!(" {}. Use {} instead of {}: Save {} bytes",
i + 1, suggested_alternative, current_type, memory_reduction);
}
scirs2_core::memory::metrics::OptimizationRecommendation::ImplementCompaction { fragmentation_reduction, suggested_frequency } => {
println!(" {}. Implement Compaction: {:.2} reduction every {:?}",
i + 1, fragmentation_reduction, suggested_frequency);
}
}
}
}
}
}
Ok(())
}
#[cfg(feature = "memory_management")]
#[allow(dead_code)]
fn demo_performance_analysis() -> Result<(), Box<dyn std::error::Error>> {
println!("\n5. Performance Impact Analysis");
println!("==============================");
let profiler = MemoryProfiler::new(MemoryProfilerConfig {
enabled: false, ..Default::default()
});
let sessionid = profiler.start_session(Some("performance_analysis".to_string()));
println!("Started performance analysis session: {}", sessionid);
println!("Simulating performance-impacting allocation patterns...");
let start_time = Instant::now();
let mut allocation_count = 0;
println!(" Phase 1: High-frequency small allocations");
for i in 0..1000 {
let size = 64 + (i % 128); let event = MemoryEvent::new(
MemoryEventType::Allocation,
"HighFrequencyComponent",
size,
0x400000 + (i * size),
);
profiler.record_event(event);
allocation_count += 1;
thread::sleep(Duration::from_micros(100));
}
println!(" Phase 2: Large allocations causing memory pressure");
for i in 0..50 {
let size = 1024 * 1024 + (i * 1024 * 512); let event = MemoryEvent::new(
MemoryEventType::Allocation,
"LargeAllocationComponent",
size,
0x800000 + (i * size),
);
profiler.record_event(event);
allocation_count += 1;
thread::sleep(Duration::from_millis(50));
}
println!(" Phase 3: Fragmented allocation pattern");
for i in 0..200 {
let size = if i % 2 == 0 { 128 } else { 8192 };
let event = MemoryEvent::new(
MemoryEventType::Allocation,
"FragmentedComponent",
size,
0xC00000 + (i * 10000),
);
profiler.record_event(event);
allocation_count += 1;
if i % 4 == 0 && i > 0 {
let dealloc_event = MemoryEvent::new(
MemoryEventType::Deallocation,
"FragmentedComponent",
size,
0xC00000 + ((i - 4) * 10000),
);
profiler.record_event(dealloc_event);
}
thread::sleep(Duration::from_millis(10));
}
let total_time = start_time.elapsed();
if let Some(result) = profiler.end_session() {
println!("\n📈 Performance Impact Analysis Results:");
println!("======================================");
println!("Allocation Performance:");
println!(" Total allocations: {}", allocation_count);
println!(" Total time: {:?}", total_time);
println!(
" Allocation rate: {:.2}/sec",
allocation_count as f64 / total_time.as_secs_f64()
);
println!(
" Average allocation time: {:?}",
result.performance_impact.avg_allocation_time
);
println!(
" Total allocation overhead: {:?}",
result.performance_impact.total_allocation_time
);
println!("\nMemory System Impact:");
println!(
" Performance bottlenecks detected: {}",
result.performance_impact.performance_bottlenecks
);
println!(
" Memory bandwidth utilization: {:.2}%",
result.performance_impact.memorybandwidth_utilization * 100.0
);
println!(
" Cache miss estimate: {:.2}%",
result.performance_impact.cache_miss_estimate * 100.0
);
println!("\nMemory Usage Summary:");
println!(
" Peak memory usage: {:.2} MB",
result.session.peak_memory_usage as f64 / (1024.0 * 1024.0)
);
println!(" Components tracked: {}", result.session.component_count);
println!("\nPer-Component Analysis:");
for (component, stats) in &result.memory_report.component_stats {
println!(" {}:", component);
println!(
" Current usage: {:.2} KB",
stats.current_usage as f64 / 1024.0
);
println!(" Peak usage: {:.2} KB", stats.peak_usage as f64 / 1024.0);
println!(" Allocations: {}", stats.allocation_count);
println!(
" Avg allocation size: {:.0} bytes",
stats.avg_allocation_size
);
let reuse_ratio = if stats.peak_usage > 0 {
stats.total_allocated as f64 / stats.peak_usage as f64
} else {
0.0
};
println!(" Memory reuse ratio: {:.2}", reuse_ratio);
if stats.allocation_count > 0 {
let alloc_rate = stats.allocation_count as f64 / total_time.as_secs_f64();
println!(" Allocation rate: {:.2}/sec", alloc_rate);
if alloc_rate > 100.0 {
println!(" ⚠️ High allocation frequency may impact performance");
}
}
}
println!("\n💡 Performance Optimization Recommendations:");
if result.performance_impact.performance_bottlenecks > 0 {
println!(" • Reduce allocation frequency using buffer pooling");
println!(" • Batch small allocations to reduce overhead");
}
if result.performance_impact.cache_miss_estimate > 0.3 {
println!(" • Optimize data locality to reduce cache misses");
println!(" • Consider memory-efficient data structures");
}
if result.session.peak_memory_usage > 100 * 1024 * 1024 {
println!(" • Monitor memory usage to prevent excessive consumption");
println!(" • Implement memory usage limits and monitoring");
}
println!(" • Profile actual runtime performance to validate optimizations");
}
Ok(())
}