Memory management, virtual and residential memory
       ------------------------------------------------------------------------
       
       Memory management is a complex topic and most can be left for the kernel 
       to handle. But having a fundamental idea about where memory is
       allocated greatly helps in understanding top(1) and the memory footprint
       of applications.
       
       # Process memory address space (page)
       
       When a process starts up, the kernel assigns is a so called memory page.
       The page size depends on the architecture. On amd64 it's 2^64 - 1 bytes.
       
       Every memory allocation this process performs, returns a pointer to some
       place within this page. Forcing a pointer outside this page, will cause
       a SEGFAULT.
       
           char *w = 1; // segfault
           char *w = malloc(12); // returns pointer within page
       
       # Memory allocation (virtual memory)
       
       Let's say we allocatate 2G of memory:
       
           char *m = malloc(2*1073741824); // 2*1G in bytes
       
       This will grab 2G of consecutive address space within the process memory.
       At this point, the memory is likely available but not guaranteed. The
       allocation shows up in top(1) as "SIZE" or on linux as "VIRT"ual memory.
       This memory is not actually used. So nothing has been written to the
       physical RAM chip in your computer.
       
       # Using memory (residential memory)
       
       Once memory gets used, it will actually use up space on your RAM chip.
       
           memset(m, 'u', 1073741824);
       
       Now we've written the character "u" to the first 1G of our allocated
       memory. If we look at top(), we'll see something like this:
       
         PID      TID PRI NICE  SIZE   RES STATE     WAIT      TIME    CPU COMMAND
       96621   569318   3    0 2048M 1027M sleep/12  ttyin     0:01  1.66% ./a.out
                                 ^     ^
               allocated memory -'     `- used (written) memory
       
       Note 1: When memory is swapped to disk, it leaves the residential bucket and
       can be seen as swap->used.
       
       Note 2: Stack memory will also show up as residential when used. Unused stack
       memory will *not* show up as virtual memory.
       
       Note 3: Residential memory includes shared memory as well. If you see 10
       chrome processes which are consuming 300MB of residential memory each, this
       does *not* mean that chrome as a whole is using 3000MB.
       
       TODO: Find out how the shared memory part of RES can be seen on OpenBSD.
       (Linux has SHR in top)
       
       # Changelog:
       # * 2021-09-26: Created
       # * 2021-09-26: + segfault example
       # * 2021-11-01: s/1G/2G/g in the paragraph below malloc()