re_memory/
peak_memory_stats.rs1use std::thread::JoinHandle;
4
5use crossbeam::channel::{Receiver, Sender};
6
7use crate::TrackingStatistics;
8use crate::accounting_allocator::{self, is_tracking_callstacks};
9
10struct Shutdown;
11
12pub struct PeakMemoryStats {
19 shutdown_tx: Sender<Shutdown>,
20 handle: JoinHandle<Option<TrackingStatistics>>,
21}
22
23impl PeakMemoryStats {
24 pub fn start() -> Self {
26 if !is_tracking_callstacks() {
27 re_log::warn_once!(
28 "Callstack tracking is disabled - peak memory use will not be collected"
29 );
30 }
31
32 let (shutdown_tx, shutdown_rx) = crossbeam::channel::bounded(1);
33 let handle = std::thread::Builder::new()
34 .name("PeakMemoryStates".to_owned())
35 .spawn(move || collect_peak_memory_use(&shutdown_rx))
36 .expect("Failed to spawn PeakMemoryStates thread");
37 Self {
38 shutdown_tx,
39 handle,
40 }
41 }
42
43 pub fn finish(self) -> Option<TrackingStatistics> {
44 let Self {
45 shutdown_tx,
46 handle,
47 } = self;
48
49 shutdown_tx.send(Shutdown).ok();
50
51 match handle.join() {
52 Err(err) => {
53 re_log::warn_once!("Failed to collect PeakMemoryStates: {err:?}"); None
55 }
56 Ok(result) => result,
57 }
58 }
59}
60
61fn current_memory_use() -> usize {
62 if let Some(stats) = crate::accounting_allocator::global_allocs() {
63 stats.size
64 } else {
65 re_log::error_once!("accounting_allocator is OFF. Can't collect peak memory use");
66 0
67 }
68}
69
70fn collect_peak_memory_use(shutdown_rx: &Receiver<Shutdown>) -> Option<TrackingStatistics> {
71 let interval = std::time::Duration::from_secs(5);
73
74 let watermark_margin = 100 * 1024 * 1024;
75
76 let mut highest_memory_use = current_memory_use();
77 let mut highest_so_far = accounting_allocator::tracking_stats();
78
79 loop {
80 crossbeam::select! {
82 recv(shutdown_rx) -> _ => {
83 return highest_so_far;
85 }
86 default(interval) => {
87 let current_memory_use = current_memory_use();
88
89 if highest_memory_use + watermark_margin < current_memory_use {
90 highest_memory_use = current_memory_use;
91 highest_so_far = accounting_allocator::tracking_stats();
92 }
93 }
94 }
95 }
96}