-
Notifications
You must be signed in to change notification settings - Fork 14k
Description
When compiling a project of mine, my PC with 32GB of RAM went OOM. I reduced the problem to the following code:
use std::collections::HashMap;
static TESTDATA: &str = include_str!("../testdata");
fn parse_testdata() -> HashMap<(), ()> {
let mut map = HashMap::new();
for line in TESTDATA.lines() {
}
map
}
pub fn do_stuff() {
let (tx, _) = std::sync::mpsc::channel();
let testdata = parse_testdata();
tx.send(vec![0]).unwrap();
}
fn main() {
do_stuff();
}Compiling this code with /usr/bin/time -v cargo build --release shows a maximum resident RAM usage of 16GB if testdata is generated with python -c "print('foo bar baz qux 1337 42\n' * 4_500_000)" > testdata (103MB). In debug mode, only 1.3GB RAM are used. It doesn't matter if edition is 2018 or not.
Here are some different testdata sizes with their compilation memory usage:
| python generation | size | RAM | comment |
|---|---|---|---|
'foo bar baz qux 1337 42\n' * 4_500_000 |
103MB | 16GB | file structure similar to my real-world use-case |
'foo bar baz qux 1337 42 ' * 4_500_000 |
103MB | 16GB | newlines don't matter |
'a' * 100*1024*1024 |
100MB | 15.7GB | we can reduce this to simple file size |
'a' * 80*1024*1024 |
80MB | 14GB | |
'a' * 50*1024*1024 |
50MB | 8GB | |
'a' * 25*1024*1024 |
25MB | 3.9GB | |
'a' * 10*1024*1024 |
10MB | 1.9GB | |
'a' * 1*1024*1024 |
1MB | 256MB |
If anything in the code is changed, the problem gets slightly better. Here is the RAM usage after some small changes for 100MB (for comparison, include_str just with a hello-world requires 670MB):
- use a
Vecinstead of theHashMap: 2.5GB - create the HashMap at the end of of the
parse_testdatafunction: 6GB - inline the
parse_testdatafunction manually: 6GB - make
parse_testdatanot return anything and remove the HashMap from the function: 2.5GB - send
()instead ofvec![0]: 6GB - remove the channel creation and sending into it: 4.4GB
- don't call
do_stuff: 672MB
Meta
uname -a: Linux 5.5.4-arch1-1-vfio #1 SMP PREEMPT Wed, 19 Feb 2020 15:49:02 +0000 x86_64 GNU/Linux (Archlinux)
Tested on (always testing with 100MB):
- current stable:
rustc 1.42.0 (b8cedc004 2020-03-09): 16GB - current nightly:
rustc 1.43.0-nightly (45ebd5808 2020-03-15): 16GB rustc 1.41.1 (f3e1a954d 2020-02-24): 16GBrustc 1.41.0 (5e1a79984 2020-01-27): 16GBrustc 1.40.0 (73528e339 2019-12-16): 2.5GBrustc 1.39.0 (4560ea788 2019-11-04): 2.5GBrustc 1.38.0 (625451e37 2019-09-23): 6GBrustc 1.35.0 (3c235d560 2019-05-20): 6GBrustc 1.34.0 (91856ed52 2019-04-10): 6GBrustc 1.32.0 (9fda7c223 2019-01-16): 8GBrustc 1.30.0 (da5f414c2 2018-10-24): 5GB