1pub mod analysis;
10pub mod analysis_engine;
12pub mod core;
14
15pub mod capture;
16pub mod event_store;
18pub mod facade;
20pub mod metadata;
22pub mod query;
24pub mod render_engine;
26pub mod snapshot;
28pub mod memory {
30 pub use crate::snapshot::memory::*;
31}
32pub mod timeline;
34pub mod tracker;
36
37pub use capture::backends::global_tracking::{
39 global_tracker, init_global_tracking, init_global_tracking_with_config, is_initialized,
40 GlobalTracker, GlobalTrackerConfig, GlobalTrackerStats, TrackerConfig,
41};
42
43pub mod error;
45pub mod tracking;
47pub mod utils;
49pub mod variable_registry;
51
52pub use analysis::*;
53pub use capture::backends::bottleneck_analysis::{BottleneckKind, PerformanceIssue};
54pub use capture::backends::hotspot_analysis::{CallStackHotspot, MemoryUsagePeak};
55pub use capture::backends::{
56 configure_tracking_strategy, get_tracker as get_capture_tracker, AllocationCategory,
57 AnalysisSummary, AsyncAllocation, AsyncBackend, AsyncMemorySnapshot, AsyncSnapshot, AsyncStats,
58 AsyncTracker, CoreBackend, Event, EventType, FrequencyData, FrequencyPattern, InteractionType,
59 LockfreeAnalysis, LockfreeBackend, RuntimeEnvironment, SamplingConfig, SystemMetrics, TaskInfo,
60 TaskMemoryProfile, ThreadInteraction, ThreadLocalTracker, ThreadStats, TrackedFuture,
61 TrackingStrategy, UnifiedBackend,
62};
63pub use capture::backends::{
64 is_tracking, memory_snapshot, quick_trace, stop_tracing, trace_all, trace_thread,
65};
66pub use capture::types::{AllocationInfo, SmartPointerInfo, TrackingError, TrackingResult};
67pub use capture::{CaptureBackend, CaptureBackendType, CaptureEngine};
68pub use core::allocator::TrackingAllocator;
69pub use core::tracker::{get_tracker, MemoryTracker};
70pub use core::{ExportMode, ExportOptions};
71pub use core::{MemScopeError, MemScopeResult};
72#[cfg(feature = "derive")]
73pub use memscope_derive::Trackable;
74pub use snapshot::engine::SnapshotEngine;
75pub use snapshot::memory::{
76 BoundedHistory, BoundedHistoryConfig, BoundedHistoryStats, MemoryConfig, TimestampedEntry,
77};
78pub use snapshot::types::{ActiveAllocation, MemorySnapshot, MemoryStats, ThreadMemoryStats};
79#[cfg(feature = "tracking-allocator")]
82#[global_allocator]
83pub static GLOBAL: TrackingAllocator = TrackingAllocator::new();
84pub trait Trackable {
86 fn get_heap_ptr(&self) -> Option<usize>;
88 fn get_type_name(&self) -> &'static str;
90 fn get_size_estimate(&self) -> usize;
92 fn get_ref_count(&self) -> Option<usize> {
94 None
95 }
96 fn get_data_ptr(&self) -> Option<usize>;
98 fn get_data_size(&self) -> Option<usize>;
100}
101
102impl<T> Trackable for Vec<T> {
103 fn get_heap_ptr(&self) -> Option<usize> {
104 Some(self.as_ptr() as usize)
105 }
106 fn get_type_name(&self) -> &'static str {
107 "Vec<T>"
108 }
109 fn get_size_estimate(&self) -> usize {
110 std::mem::size_of::<T>() * self.capacity()
111 }
112 fn get_data_ptr(&self) -> Option<usize> {
113 Some(self.as_ptr() as usize)
114 }
115 fn get_data_size(&self) -> Option<usize> {
116 Some(std::mem::size_of::<T>() * self.len())
117 }
118}
119
120impl Trackable for String {
121 fn get_heap_ptr(&self) -> Option<usize> {
122 Some(self.as_ptr() as usize)
123 }
124 fn get_type_name(&self) -> &'static str {
125 "String"
126 }
127 fn get_size_estimate(&self) -> usize {
128 self.capacity()
129 }
130 fn get_data_ptr(&self) -> Option<usize> {
131 Some(self.as_ptr() as usize)
132 }
133 fn get_data_size(&self) -> Option<usize> {
134 Some(self.len())
135 }
136}
137
138impl<K, V> Trackable for std::collections::HashMap<K, V> {
139 fn get_heap_ptr(&self) -> Option<usize> {
140 None
141 }
142 fn get_type_name(&self) -> &'static str {
143 "HashMap<K, V>"
144 }
145 fn get_size_estimate(&self) -> usize {
146 std::mem::size_of::<(K, V)>() * self.capacity()
147 }
148 fn get_data_ptr(&self) -> Option<usize> {
149 None
150 }
151 fn get_data_size(&self) -> Option<usize> {
152 Some(std::mem::size_of::<(K, V)>() * self.len())
153 }
154}
155
156impl<K, V> Trackable for std::collections::BTreeMap<K, V> {
157 fn get_heap_ptr(&self) -> Option<usize> {
158 None
159 }
160 fn get_type_name(&self) -> &'static str {
161 "BTreeMap<K, V>"
162 }
163 fn get_size_estimate(&self) -> usize {
164 std::mem::size_of::<(K, V)>() * self.len()
165 }
166 fn get_data_ptr(&self) -> Option<usize> {
167 None
168 }
169 fn get_data_size(&self) -> Option<usize> {
170 Some(std::mem::size_of::<(K, V)>() * self.len())
171 }
172}
173
174impl<T> Trackable for std::collections::VecDeque<T> {
175 fn get_heap_ptr(&self) -> Option<usize> {
176 None
177 }
178 fn get_type_name(&self) -> &'static str {
179 "VecDeque<T>"
180 }
181 fn get_size_estimate(&self) -> usize {
182 std::mem::size_of::<T>() * self.capacity()
183 }
184 fn get_data_ptr(&self) -> Option<usize> {
185 None
186 }
187 fn get_data_size(&self) -> Option<usize> {
188 Some(std::mem::size_of::<T>() * self.len())
189 }
190}
191
192impl<T> Trackable for Box<T> {
193 fn get_heap_ptr(&self) -> Option<usize> {
194 Some(&**self as *const T as usize)
195 }
196 fn get_type_name(&self) -> &'static str {
197 "Box<T>"
198 }
199 fn get_size_estimate(&self) -> usize {
200 std::mem::size_of::<T>()
201 }
202 fn get_data_ptr(&self) -> Option<usize> {
203 Some(&**self as *const T as usize)
204 }
205 fn get_data_size(&self) -> Option<usize> {
206 Some(std::mem::size_of::<T>())
207 }
208}
209
210impl<T> Trackable for std::rc::Rc<T> {
211 fn get_heap_ptr(&self) -> Option<usize> {
212 Some(&**self as *const T as usize)
213 }
214 fn get_type_name(&self) -> &'static str {
215 "Rc<T>"
216 }
217 fn get_size_estimate(&self) -> usize {
218 std::mem::size_of::<T>()
219 }
220 fn get_ref_count(&self) -> Option<usize> {
221 Some(std::rc::Rc::strong_count(self))
222 }
223 fn get_data_ptr(&self) -> Option<usize> {
224 Some(&**self as *const T as usize)
225 }
226 fn get_data_size(&self) -> Option<usize> {
227 Some(std::mem::size_of::<T>())
228 }
229}
230
231impl<T> Trackable for std::sync::Arc<T> {
232 fn get_heap_ptr(&self) -> Option<usize> {
233 Some(&**self as *const T as usize)
234 }
235 fn get_type_name(&self) -> &'static str {
236 "Arc<T>"
237 }
238 fn get_size_estimate(&self) -> usize {
239 std::mem::size_of::<T>()
240 }
241 fn get_ref_count(&self) -> Option<usize> {
242 Some(std::sync::Arc::strong_count(self))
243 }
244 fn get_data_ptr(&self) -> Option<usize> {
245 Some(&**self as *const T as usize)
246 }
247 fn get_data_size(&self) -> Option<usize> {
248 Some(std::mem::size_of::<T>())
249 }
250}
251
252impl<T: Trackable> Trackable for std::cell::RefCell<T> {
253 fn get_heap_ptr(&self) -> Option<usize> {
254 None
255 }
256 fn get_type_name(&self) -> &'static str {
257 "RefCell<T>"
258 }
259 fn get_size_estimate(&self) -> usize {
260 std::mem::size_of::<T>()
261 }
262 fn get_data_ptr(&self) -> Option<usize> {
263 None
264 }
265 fn get_data_size(&self) -> Option<usize> {
266 Some(std::mem::size_of::<T>())
267 }
268}
269
270impl<T: Trackable> Trackable for std::sync::RwLock<T> {
271 fn get_heap_ptr(&self) -> Option<usize> {
272 None
273 }
274 fn get_type_name(&self) -> &'static str {
275 "RwLock<T>"
276 }
277 fn get_size_estimate(&self) -> usize {
278 std::mem::size_of::<T>()
279 }
280 fn get_data_ptr(&self) -> Option<usize> {
281 None
282 }
283 fn get_data_size(&self) -> Option<usize> {
284 Some(std::mem::size_of::<T>())
285 }
286}