RustCrypto / password-hashes

Password hashing functions / KDFs
652 stars 80 forks source link

Argon2 - memory use #486

Closed mrjackwills closed 8 months ago

mrjackwills commented 8 months ago

I think I am suffering from the same memory issue as detailed in issue 478.

The application is as so;

use argon2::{
    password_hash::{PasswordHash, PasswordVerifier},
    Argon2,
};

fn main() {
    std::thread::sleep(std::time::Duration::from_secs(5));
    println!("Starting");
        for _ in 1..=300 {
            let parsed_hash = PasswordHash::new(
                r#"$argon2i$v=19$m=19000,t=2,p=1$a280Y05CQjVrWWxZQjBEaw$moMWFS2AVx0lvSndhzFrWQ"#,
            )
            .unwrap();
            let t = Argon2::default().verify_password("password".as_bytes(), &parsed_hash);
            println!("{}", t.is_ok());
        }
    println!("Finished");
    std::thread::sleep(std::time::Duration::from_secs(10_000));
}

After "Finished" is printed to stdout, the application is still reportedly holding on to 150mb of memory. This has been tested on my home x86 Debian linux laptop, and a remote x86 Ubuntu linux server.

However, building for x86_64-unknown-linux-musl the memory gets freed immediately when you'd expect. So my guess is that this is something related to the x86 gnu build/run step - this area of Rust goes slightly over my head.

I don't know what the most reliable way to record memory usage/held memory is. I was was just a combination of htop, ps, and top. I can provide some kind of screen recording would offer any kind of help.

newpavlov commented 8 months ago

After "Finished" is printed to stdout, the application is still reportedly holding on to 150mb of memory.

It's simply how allocators work. They often do not release memory to OS immediately and release itself is done using MADV_FREE, so pages would continue to "belong" to an application until OS experiences significant memory pressure.

mrjackwills commented 8 months ago

Yeah I guessed it was something simple like that, I was just having trouble as my application is run in a Docker container that has an artificially constrained memory limit. I will just increase the limit - or build for musl.