Search code examples
memoryprocessramdeterministic

Why does the same process ran twice does not use exactly the same quantity of memory?


Consider MyProcess, a purely deterministic process. If I run this process several times measuring the max memory usage with usz time I get

time ./MyProcess
max memory:                86624 KB

time ./MyProcess
max memory:                85740 KB

time ./MyProcess
max memory:                86156 KB

The measures of RAM usage are quite similar of course but they differ a little bit. What create these differences?

  • Is it because the max memory is calculated as the maximum observed RAM usage over several point measurement through time. The max memory is actually exactly the same.
  • Is it because even in deterministic processes, there are small differences that can be caused for example by the RAM available when allocation of memory occurs
  • other reasons...

FYI, I use MACOSX 10.11.3


Solution

  • This is most likely due to Address Space Layout Randomization, aka ASLR.

    Modern OS shift and shuffle a process's memory layout on each new execution so that attackers will not know where the interesting addresses are.

    Normally programmers don't notice, except through small changes in used memory or that all pointers have different values (causing e.g. different iteration order through hash tables keyed on pointers).

    Here's an example program for Linux, which also does ASLR:

    #include <stdio.h>
    
    int main() {
      char c;
      printf("Address: %lx\n", &c);
      return 0;
    }
    

    If we run it multiple times, we see different addresses and memory usage:

    $ gcc foo.c -o foo
    
    $ command time -f 'Memory: %M' ./foo
    Address: 7ffc1995f2df
    Memory: 1288
    
    $ command time -f 'Memory: %M' ./foo
    Address: 7ffcdfd2427f
    Memory: 1324
    
    $ command time -f 'Memory: %M' ./foo
    Address: 7ffe3022a23f
    Memory: 1368
    

    If we disable ASLR (this is Linux specific and does not work on OSX) with:

    sudo tee /proc/sys/kernel/randomize_va_space <<< 0
    

    Addresses and used memory is always the same:

    $ command time -f 'Memory: %M' ./foo
    Address: 7fffffffe4bf
    Memory: 1272
    
    $ command time -f 'Memory: %M' ./foo
    Address: 7fffffffe4bf
    Memory: 1272
    
    $ command time -f 'Memory: %M' ./foo
    Address: 7fffffffe4bf
    Memory: 1272