clinuxmemorymemory-managementdemand-paging

Am I experiencing demand paging when not altering the values of a newly created array?


I'm learning about OSs memory management and just learned about virtual memory and how it can be implemented using demand paging.

I made this simple program:

#include<stdio.h>
#include<stdlib.h>

int main(void){
  int x=0;
  scanf("%d",&x);
  if(x==1){
    int *a=malloc(1073741824*sizeof(int));
    while(1){
      for(size_t i=0;i<1073741824;i++){
        a[i]=1;
      }
    }
  }
  else if(x==2){
    int *b=malloc(1073741824*sizeof(int));
    while(1);
  }
  return 0;
}

It has 2 paths:

  1. One allocated an array of 4 gb and keeps changing its values.

  2. The other allocated an array of 4 gb, but doesn't change its values.

As I expected, after running the first option, the memory of the program increases to about 4 gb, but the second one doesn't change. I'm guessing this is due to the memory not being accessed, so its pages are "swapped out" to a backing store, until they're needed again.

Is my understanding correct?


Solution

  • Demand paging is when you access pages of memory that aren't in Linux's page cache. For example, if you use memory mapping you can access a file on disk as if it were in RAM. When you dereference a memory mapped pointer Linux first checks the page cache for the data; if the page isn't in the cache then it page faults and loads the missing pages from the disk. Your program doesn't see all the on-demand disk access going on behind the scenes.

    Demand paging isn't relevant with a fresh malloc() call since there's nothing on disk. What you're seeing is called overcommit. Linux doesn't allocate memory when malloc() is called; it lies and always returns a pointer whether it can satisfy the request or not. The memory is only actually allocated when (if) you access it. If you ask for 4GB of memory but don't do anything with it nothing's actually allocated.

    Unsurprisingly, lying doesn't always work out. Linux might not actually be able to satisfy a program's memory needs, but the program has no way of knowing because malloc() didn't return NULL. It's like an airline that overbooks its flights. The airline gives you a ticket, but when you show up at the airport they tell you they ran out of seats and kick you off the flight. You try to access the memory you allocated and Linux panics, invokes the OOM killer, and starts killing processes to free up memory. Who does it kill? Maybe your process. Maybe you're spared and others die. Suffice it to say, overcommit is a controversial feature.