2
votes

I've the following code

use jemalloc_ctl::{stats, epoch};
use jemallocator;
#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    let my_structs = vec![3];

    let allocated_bytes: usize = current();
    {
        for _i in 0..4782 {
            let _a: Vec<&i32> = my_structs
                .iter()
                .collect();
        }
    }

    let allocated_bytes_after: usize = current();
    println!("before allocated_bytes: {}", allocated_bytes);
    println!("after   allocated_bytes: {}", allocated_bytes_after);
    println!("DIFF allocated_bytes: {}", allocated_bytes_after - allocated_bytes);

    Ok(())
}

fn current() -> usize {
    epoch::advance().unwrap();
    stats::allocated::read().unwrap()
}

The output confirms that the diff is 0 bytes as expected

Anyway if I change the iteration upper limit from 4782 to 4783 the result changes: the program exits with panic because the allocated_bytes_after is less than allocated_bytes.

This is a strange behavior. Why the memory allocation is less after? Why the limit is 4782?

I'm using:

$ cargo version
cargo 1.43.0 (2cbe9048e 2020-05-03)
Better question is why not ?Stargateur
@Stargateur what do you mean?Thomas8
what said that allocate memory can't be less after allocation operation ? Specially if you free them. Why allocator shouldn't be allowed to optimize memory or anything else ? You ask why it's less but the question is why it should not be less ? Try to answer this question the result will be "It can be less because it's not specified in jemalloc implementation". this look like you try to rely on unspecified behaviour. (AFAIK)Stargateur
Rust doesn't use garbage collector, so I immagine that the memory management is made on end of blocks. So increasing by one the iteration loop doesn't produce a memory fee of previous variables. From your point of view, which variable is freed changing from 4782 to 4783 ? This behaviour is constant.allevo