re_memory/
memory_use.rs

1/// How much RAM is the application using?
2#[derive(Copy, Clone, Debug, PartialEq, Eq)]
3pub struct MemoryUse {
4    /// Bytes allocated by the application according to operating system.
5    ///
6    /// Resident Set Size (RSS) on Linux, Android, Mac, iOS.
7    /// Working Set on Windows.
8    ///
9    /// `None` if unknown.
10    pub resident: Option<i64>,
11
12    /// Bytes used by the application according to our own memory allocator's accounting.
13    ///
14    /// This can be smaller than [`Self::resident`] because our memory allocator may not
15    /// return all the memory we free to the OS.
16    ///
17    /// `None` if [`crate::AccountingAllocator`] is not used.
18    pub counted: Option<i64>,
19}
20
21impl MemoryUse {
22    /// Read the current memory of the running application.
23    #[inline]
24    pub fn capture() -> Self {
25        Self {
26            resident: bytes_resident(),
27            counted: crate::accounting_allocator::global_allocs().map(|c| c.size as _),
28        }
29    }
30
31    /// Bytes used by the application according to our best estimate.
32    ///
33    /// This is either [`Self::counted`] if it's available, otherwise fallbacks to
34    /// [`Self::resident`] if that's available, otherwise `None`.
35    #[inline]
36    pub fn used(&self) -> Option<i64> {
37        self.counted.or(self.resident)
38    }
39}
40
41impl std::ops::Mul<f32> for MemoryUse {
42    type Output = Self;
43
44    fn mul(self, factor: f32) -> Self::Output {
45        Self {
46            resident: self.resident.map(|v| (v as f32 * factor) as i64),
47            counted: self.counted.map(|v| (v as f32 * factor) as i64),
48        }
49    }
50}
51
52impl std::ops::Sub for MemoryUse {
53    type Output = Self;
54
55    #[inline]
56    fn sub(self, rhs: Self) -> Self::Output {
57        fn sub(a: Option<i64>, b: Option<i64>) -> Option<i64> {
58            Some(a? - b?)
59        }
60
61        Self {
62            resident: sub(self.resident, rhs.resident),
63            counted: sub(self.counted, rhs.counted),
64        }
65    }
66}
67
68// ----------------------------------------------------------------------------
69
70/// According to the OS. This is what matters.
71///
72/// Resident Set Size (RSS) on Linux, Android, Mac, iOS.
73/// Working Set on Windows.
74#[cfg(not(target_arch = "wasm32"))]
75fn bytes_resident() -> Option<i64> {
76    memory_stats::memory_stats().map(|usage| usage.physical_mem as i64)
77}
78
79#[cfg(target_arch = "wasm32")]
80fn bytes_resident() -> Option<i64> {
81    // blocked on https://github.com/Arc-blroth/memory-stats/issues/1
82    None
83}