How much memory does my Rust process use?

memory-stats thousands

In my quest to be able to report and analyze the memory footprint of my process I found the memory-stats crate. In the documentation you can see how this crate works. At least on Linux it relies on the memory accounting of the Operating System.

I also used the thousands crate to commafy big numbers.

See also the article memory allocation and usage where I checked the total memory used and the available free memory in the computer.

Dependencies

examples/using-memory-stats/Cargo.toml

[package]
name = "using-memory-stats"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
memory-stats = { version = "1.1.0", features = ["always_use_statm"] }
thousands = "0.2.0"

The Code

Basically we fetch the

  • "Physical" Memory, which corresponds to the Resident Set Size on Linux and MacOS and the Working Set on Windows.
  • "Virtual" Memory, which corresponds to the Virtual Size on Linux and MacOS and the Pagefile Usage on Windows.

both before and after creating a variable with many characters in it and the print the differences.

examples/using-memory-stats/src/main.rs

use memory_stats::memory_stats;
use thousands::Separable;

fn main() {
    show_mem();

    println!("Bytes            Physical memory   Virtual memory  ");
    check_mem(10000);
    check_mem(100000);
    check_mem(1000000);
    check_mem(10000000);
    check_mem(100000000);
    check_mem(1000000000);
    check_mem(10000000000);
}

fn check_mem(bytes: usize) {
    let before = memory_stats().unwrap();
    let _text = String::from("x".repeat(bytes));
    let after = memory_stats().unwrap();

    let physical_mem = after.physical_mem - before.physical_mem;
    let virtual_mem = after.virtual_mem - before.virtual_mem;
    println!(
        "{:>15} {:>15} {:>15}",
        bytes.separate_with_commas(),
        physical_mem.separate_with_commas(),
        virtual_mem.separate_with_commas()
    )
}

fn show_mem() {
    if let Some(usage) = memory_stats() {
        println!(
            "Physical memory usage: {:>15}",
            usage.physical_mem.separate_with_commas()
        );
        println!(
            "Virtual memory usage:  {:>15}",
            usage.virtual_mem.separate_with_commas()
        );
    } else {
        println!("Couldn't get the current memory usage :(");
    }
}

The results

I ran the process 3 times to see how consistent are the results. (Acaully I ran many more times, but let me show only 3 results here):

For 10,000 and 100,000 bytes I got 0 change in 2 of the executions and got a single 131,072 change for the 3rd run. Starting from 1,000,000 bytes the results were fairly consisten accross the 3 runs and they also indicate a change in used memory similar to the siez of the created string.

$ cargo run -q
Physical memory usage:       1,966,080
Virtual memory usage:        3,338,240
Bytes            Physical memory   Virtual memory
         10,000               0               0
        100,000               0               0
      1,000,000       1,048,576       1,003,520
     10,000,000       9,961,472      10,002,432
    100,000,000      99,876,864     100,003,840
  1,000,000,000     999,948,288   1,000,001,536
 10,000,000,000   9,999,876,096  10,000,003,072

$ cargo run -q
Physical memory usage:       1,966,080
Virtual memory usage:        3,338,240
Bytes            Physical memory   Virtual memory
         10,000               0               0
        100,000               0               0
      1,000,000       1,048,576       1,003,520
     10,000,000       9,961,472      10,002,432
    100,000,000      99,876,864     100,003,840
  1,000,000,000     999,817,216   1,000,001,536
 10,000,000,000   9,999,876,096  10,000,003,072

$ cargo run -q
Physical memory usage:       1,835,008
Virtual memory usage:        3,338,240
Bytes            Physical memory   Virtual memory
         10,000         131,072               0
        100,000               0               0
      1,000,000       1,048,576       1,003,520
     10,000,000       9,961,472      10,002,432
    100,000,000      99,876,864     100,003,840
  1,000,000,000     999,948,288   1,000,001,536
 10,000,000,000   9,999,876,096  10,000,003,072

Related Pages

Memory allocation and usage in Rust
Memory allocation and usage in Rust

Author

Gabor Szabo (szabgab)

Gabor Szabo, the author of the Rust Maven web site maintains several Open source projects in Rust and while he still feels he has tons of new things to learn about Rust he already offers training courses in Rust and still teaches Python, Perl, git, GitHub, GitLab, CI, and testing.

Gabor Szabo