pub mod analysis;
pub mod analysis_engine;
pub mod core;
pub mod capture;
pub mod event_store;
pub mod facade;
pub mod metadata;
pub mod query;
pub mod render_engine;
pub mod snapshot;
pub mod memory {
pub use crate::snapshot::memory::*;
}
pub mod timeline;
pub mod tracker;
pub use capture::backends::global_tracking::{
global_tracker, init_global_tracking, init_global_tracking_with_config, is_initialized,
GlobalTracker, GlobalTrackerConfig, GlobalTrackerStats, TrackerConfig,
};
pub mod error;
pub mod tracking;
pub mod utils;
pub mod variable_registry;
pub use analysis::*;
pub use capture::backends::bottleneck_analysis::{BottleneckKind, PerformanceIssue};
pub use capture::backends::hotspot_analysis::{CallStackHotspot, MemoryUsagePeak};
pub use capture::backends::{
configure_tracking_strategy, get_tracker as get_capture_tracker, AllocationCategory,
AnalysisSummary, AsyncAllocation, AsyncBackend, AsyncMemorySnapshot, AsyncSnapshot, AsyncStats,
AsyncTracker, CoreBackend, Event, EventType, FrequencyData, FrequencyPattern, InteractionType,
LockfreeAnalysis, LockfreeBackend, RuntimeEnvironment, SamplingConfig, SystemMetrics, TaskInfo,
TaskMemoryProfile, ThreadInteraction, ThreadLocalTracker, ThreadStats, TrackedFuture,
TrackingStrategy, UnifiedBackend,
};
pub use capture::backends::{
is_tracking, memory_snapshot, quick_trace, stop_tracing, trace_all, trace_thread,
};
pub use capture::types::{AllocationInfo, SmartPointerInfo, TrackingError, TrackingResult};
pub use capture::{CaptureBackend, CaptureBackendType, CaptureEngine};
pub use core::allocator::TrackingAllocator;
pub use core::tracker::{get_tracker, MemoryTracker};
pub use core::{ExportMode, ExportOptions};
pub use core::{MemScopeError, MemScopeResult};
#[cfg(feature = "derive")]
pub use memscope_derive::Trackable;
pub use snapshot::engine::SnapshotEngine;
pub use snapshot::memory::{
BoundedHistory, BoundedHistoryConfig, BoundedHistoryStats, MemoryConfig, TimestampedEntry,
};
pub use snapshot::types::{ActiveAllocation, MemorySnapshot, MemoryStats, ThreadMemoryStats};
#[cfg(feature = "tracking-allocator")]
#[global_allocator]
pub static GLOBAL: TrackingAllocator = TrackingAllocator::new();
pub trait Trackable {
fn get_heap_ptr(&self) -> Option<usize>;
fn get_type_name(&self) -> &'static str;
fn get_size_estimate(&self) -> usize;
fn get_ref_count(&self) -> Option<usize> {
None
}
fn get_data_ptr(&self) -> Option<usize>;
fn get_data_size(&self) -> Option<usize>;
}
impl<T> Trackable for Vec<T> {
fn get_heap_ptr(&self) -> Option<usize> {
Some(self.as_ptr() as usize)
}
fn get_type_name(&self) -> &'static str {
"Vec<T>"
}
fn get_size_estimate(&self) -> usize {
std::mem::size_of::<T>() * self.capacity()
}
fn get_data_ptr(&self) -> Option<usize> {
Some(self.as_ptr() as usize)
}
fn get_data_size(&self) -> Option<usize> {
Some(std::mem::size_of::<T>() * self.len())
}
}
impl Trackable for String {
fn get_heap_ptr(&self) -> Option<usize> {
Some(self.as_ptr() as usize)
}
fn get_type_name(&self) -> &'static str {
"String"
}
fn get_size_estimate(&self) -> usize {
self.capacity()
}
fn get_data_ptr(&self) -> Option<usize> {
Some(self.as_ptr() as usize)
}
fn get_data_size(&self) -> Option<usize> {
Some(self.len())
}
}
impl<K, V> Trackable for std::collections::HashMap<K, V> {
fn get_heap_ptr(&self) -> Option<usize> {
None
}
fn get_type_name(&self) -> &'static str {
"HashMap<K, V>"
}
fn get_size_estimate(&self) -> usize {
std::mem::size_of::<(K, V)>() * self.capacity()
}
fn get_data_ptr(&self) -> Option<usize> {
None
}
fn get_data_size(&self) -> Option<usize> {
Some(std::mem::size_of::<(K, V)>() * self.len())
}
}
impl<K, V> Trackable for std::collections::BTreeMap<K, V> {
fn get_heap_ptr(&self) -> Option<usize> {
None
}
fn get_type_name(&self) -> &'static str {
"BTreeMap<K, V>"
}
fn get_size_estimate(&self) -> usize {
std::mem::size_of::<(K, V)>() * self.len()
}
fn get_data_ptr(&self) -> Option<usize> {
None
}
fn get_data_size(&self) -> Option<usize> {
Some(std::mem::size_of::<(K, V)>() * self.len())
}
}
impl<T> Trackable for std::collections::VecDeque<T> {
fn get_heap_ptr(&self) -> Option<usize> {
None
}
fn get_type_name(&self) -> &'static str {
"VecDeque<T>"
}
fn get_size_estimate(&self) -> usize {
std::mem::size_of::<T>() * self.capacity()
}
fn get_data_ptr(&self) -> Option<usize> {
None
}
fn get_data_size(&self) -> Option<usize> {
Some(std::mem::size_of::<T>() * self.len())
}
}
impl<T> Trackable for Box<T> {
fn get_heap_ptr(&self) -> Option<usize> {
Some(&**self as *const T as usize)
}
fn get_type_name(&self) -> &'static str {
"Box<T>"
}
fn get_size_estimate(&self) -> usize {
std::mem::size_of::<T>()
}
fn get_data_ptr(&self) -> Option<usize> {
Some(&**self as *const T as usize)
}
fn get_data_size(&self) -> Option<usize> {
Some(std::mem::size_of::<T>())
}
}
impl<T> Trackable for std::rc::Rc<T> {
fn get_heap_ptr(&self) -> Option<usize> {
Some(&**self as *const T as usize)
}
fn get_type_name(&self) -> &'static str {
"Rc<T>"
}
fn get_size_estimate(&self) -> usize {
std::mem::size_of::<T>()
}
fn get_ref_count(&self) -> Option<usize> {
Some(std::rc::Rc::strong_count(self))
}
fn get_data_ptr(&self) -> Option<usize> {
Some(&**self as *const T as usize)
}
fn get_data_size(&self) -> Option<usize> {
Some(std::mem::size_of::<T>())
}
}
impl<T> Trackable for std::sync::Arc<T> {
fn get_heap_ptr(&self) -> Option<usize> {
Some(&**self as *const T as usize)
}
fn get_type_name(&self) -> &'static str {
"Arc<T>"
}
fn get_size_estimate(&self) -> usize {
std::mem::size_of::<T>()
}
fn get_ref_count(&self) -> Option<usize> {
Some(std::sync::Arc::strong_count(self))
}
fn get_data_ptr(&self) -> Option<usize> {
Some(&**self as *const T as usize)
}
fn get_data_size(&self) -> Option<usize> {
Some(std::mem::size_of::<T>())
}
}
impl<T: Trackable> Trackable for std::cell::RefCell<T> {
fn get_heap_ptr(&self) -> Option<usize> {
None
}
fn get_type_name(&self) -> &'static str {
"RefCell<T>"
}
fn get_size_estimate(&self) -> usize {
std::mem::size_of::<T>()
}
fn get_data_ptr(&self) -> Option<usize> {
None
}
fn get_data_size(&self) -> Option<usize> {
Some(std::mem::size_of::<T>())
}
}
impl<T: Trackable> Trackable for std::sync::RwLock<T> {
fn get_heap_ptr(&self) -> Option<usize> {
None
}
fn get_type_name(&self) -> &'static str {
"RwLock<T>"
}
fn get_size_estimate(&self) -> usize {
std::mem::size_of::<T>()
}
fn get_data_ptr(&self) -> Option<usize> {
None
}
fn get_data_size(&self) -> Option<usize> {
Some(std::mem::size_of::<T>())
}
}