Skip to content

OOM (huge memory usage) during release compilation with include_str of 100MB #70035

Open
@oberien

Description

@oberien

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 Vec instead of the HashMap: 2.5GB
  • create the HashMap at the end of of the parse_testdata function: 6GB
  • inline the parse_testdata function manually: 6GB
  • make parse_testdata not return anything and remove the HashMap from the function: 2.5GB
  • send () instead of vec![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): 16GB
  • rustc 1.41.0 (5e1a79984 2020-01-27): 16GB
  • rustc 1.40.0 (73528e339 2019-12-16): 2.5GB
  • rustc 1.39.0 (4560ea788 2019-11-04): 2.5GB
  • rustc 1.38.0 (625451e37 2019-09-23): 6GB
  • rustc 1.35.0 (3c235d560 2019-05-20): 6GB
  • rustc 1.34.0 (91856ed52 2019-04-10): 6GB
  • rustc 1.32.0 (9fda7c223 2019-01-16): 8GB
  • rustc 1.30.0 (da5f414c2 2018-10-24): 5GB

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-compilememIssue: Problems and improvements with respect to memory usage during compilation.P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions