memory_stats/lib.rs
1//! # Memory Stats
2//!
3//! A cross-platform memory profiler for Rust, supporting Windows, Linux, and MacOS. This crate provides two metrics:
4//!
5//! - **"Physical" Memory**, which corresponds to the _Resident Set Size_ on Linux and MacOS and the _Working Set_ on Windows.
6//! - **"Virtual" Memory**, which corresponds to the _Virtual Size_ on Linux and MacOS and the _Pagefile Usage_ on Windows.
7//!
8//! ## Usage
9//!
10//! Add `memory-stats` as a dependency to your `Cargo.toml`:
11//!
12//! ```toml
13//! [dependencies]
14//! memory-stats = "1.0.0"
15//! ```
16//!
17//! ### Optional Features
18//!
19//! `serde`: Enables serialization and deserialization of the [`MemoryStats`] struct.
20//!
21//! ## Example
22//!
23//! Here's an example that prints out the current memory usage:
24//!
25//! ```
26//! use memory_stats::memory_stats;
27//!
28//! if let Some(usage) = memory_stats() {
29//! println!("Current physical memory usage: {}", usage.physical_mem);
30//! println!("Current virtual memory usage: {}", usage.virtual_mem);
31//! } else {
32//! println!("Couldn't get the current memory usage :(");
33//! }
34//! ```
35//!
36//! ## Caveats
37//!
38//! Getting accurate memory usage on Linux is fairly expensive and not always possible. This crate always attempts to use the statistics from
39//! [`/proc/self/smaps`](https://man7.org/linux/man-pages/man5/proc.5.html#:~:text=See%20user_namespaces%287%29.-,/proc/%5Bpid%5D/smaps,-%28since%20Linux%202.6.14)
40//! if avaliable. However, since support for `/proc/self/smaps` might not be compiled in on all kernels, this crate will also use the faster but less accurate statistics from
41//! [`/proc/self/statm`](https://man7.org/linux/man-pages/man5/proc.5.html#:~:text=by%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20waitpid%282%29.-,/proc/%5Bpid%5D/statm,-Provides%20information%20about)
42//! as a fallback.
43//!
44//! If speed is needed over accuracy, the `always_use_statm` feature can be enabled to always use the `/proc/self/statm` statistics.
45
46#[cfg(feature = "serde")]
47use serde::{Deserialize, Serialize};
48
49#[cfg(target_os = "windows")]
50#[path = "windows.rs"]
51mod platform;
52
53#[cfg(any(target_os = "linux", target_os = "android"))]
54#[path = "linux.rs"]
55mod platform;
56
57#[cfg(any(target_os = "macos", target_os = "ios"))]
58#[path = "darwin.rs"]
59mod platform;
60
61#[cfg(target_os = "freebsd")]
62#[path = "freebsd.rs"]
63mod platform;
64
65#[cfg(not(any(
66 target_os = "windows",
67 target_os = "linux",
68 target_os = "android",
69 target_os = "macos",
70 target_os = "ios",
71 target_os = "freebsd",
72)))]
73mod platform {
74 use crate::MemoryStats;
75
76 pub fn memory_stats() -> Option<MemoryStats> {
77 None
78 }
79}
80
81/// Statistics on the memory used by the current process.
82#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
83#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
84pub struct MemoryStats {
85 /// The "physical" memory used by this process, in bytes.
86 /// This corresponds to the following
87 /// metric on each platform:
88 /// - **Linux, Android, MacOS, iOS**: Resident Set Size
89 /// - **Windows**: Working Set
90 pub physical_mem: usize,
91
92 /// The "virtual" memory used by this process, in bytes.
93 /// This corresponds to the following
94 /// metric on each platform:
95 /// - **Linux, Android, MacOS, iOS**: Virtual Size
96 /// - **Windows**: Pagefile Usage
97 pub virtual_mem: usize,
98}
99
100/// Returns a snapshot of the the memory used by the
101/// current process.
102///
103/// # Errors
104///
105/// If the current memory usage cannot be queried
106/// or `memory_stats` is run on a unsupported platform,
107/// `None` is returned.
108pub fn memory_stats() -> Option<MemoryStats> {
109 platform::memory_stats()
110}