mem-ballast

Ensure a certain amount of memory is in use on a host

git clone https://code.pdelong.com/mem-ballast.git

 1use sysinfo::SystemExt;
 2
 3static PAGE_SIZE: usize = 4096;
 4static PERCENTAGE: f64 = 0.1;
 5static OVER_PERCENTAGE: f64 = 0.1;
 6
 7fn create_memory(size: usize) -> Result<memmap2::MmapMut, std::io::Error> {
 8    let mut map = memmap2::MmapOptions::new().len(size).map_anon()?;
 9    assert!(map.len() == size);
10
11    for i in (0..map.len()).step_by(PAGE_SIZE) {
12        map[i] = 0xAB;
13    }
14
15    Ok(map)
16}
17
18fn main() {
19    let mut sys = sysinfo::System::new_with_specifics(sysinfo::RefreshKind::new().with_memory());
20
21    let mut allocated = 0;
22    let mut _map: memmap2::MmapMut;
23
24    loop {
25        sys.refresh_memory();
26        println!("{}/{}", sys.used_memory(), sys.total_memory());
27        let used = sys.used_memory();
28        let total = sys.total_memory();
29
30        let mut needed = (total as f64 * PERCENTAGE) as i64 - used as i64;
31        println!("needed = {needed}, allocated = {allocated}");
32
33        if needed > 0 {
34            // Very slightly over-allocate to work around rounding issues and provide cushion to
35            // avoid re-allocating frequently
36            needed = (needed as f64 * 1.01) as i64;
37            needed += allocated as i64;
38
39            println!("allocating {needed} bytes");
40
41            _map = create_memory(needed as usize).unwrap();
42            allocated = needed as u64;
43
44            sys.refresh_memory();
45            println!("actual = {}/{}", sys.used_memory(), sys.total_memory());
46        } else if needed < -(total as f64 * OVER_PERCENTAGE) as i64 {
47            // Deallocate if we're too high
48
49            needed += allocated as i64;
50            needed = std::cmp::max(needed, 0);
51
52            println!("shrinking to {needed} bytes");
53
54            _map = create_memory(needed as usize).unwrap();
55            allocated = needed as u64;
56        }
57
58        println!();
59
60        std::thread::sleep(std::time::Duration::from_secs(60));
61    }
62}