Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

malloc behaves differently on different machines

I see totally different behavior when running a piece of program that tries to exceed RSS on different machines. The code is something like:

...
  char** s = (char**)malloc(10000*sizeof(char*));

  for (i = 0; i < 10000; i++){
    s[i] = (char*)malloc(1000*1000*sizeof(char));
    if (s[i] == NULL) {
      printf("cannot allocate memory for s[%d]",i);
      exit(1);
    }
  }

  int j = 0;
  while(1){
    for (i = 0; i < 10000; i++){
      for (j = 0; j < 1000*1000; j++) {
        s[i][j] = 1;
      }
      if ((i % 100) == 0) printf("i = %d\n", i);
    }
  }
  for (i = 0; i < 10000; i++)
    free(s[i]);
  free(s);
...

The above code tries to allocate around 10GB of memory using malloc. The first two machines I tried this code on run on linux kernel 2.6 and the last one runs linux kernel 2.4. Here are the behaviors I see on these machines:

Machine1: the memory is allocated using memory overcommit, but when assigning values to the memory locations in the while loop, it only allocates as much as RSS allows. Thus OOM Killer kills the process when i=3800 is printed which is around 4GB of memory this machine has.

Machine2: memory is allocated using memory overcommit and the while loop goes on forever, allocating pages from virtual memory. The process goes a bit slower after i = 3800 is printed which is normal.

machine3: this machines has only 2GB of memory. The memory cannot even be allocated. Seems like the over commit is not set or kernel 2.4 does not support allocating virtual machine pages using malloc! Thus in the first for loop it exits while allocating memory for i = 2138

My desired action is the one happening in machine2. Does anyone know which (kernel?) options has to be set to allow OS to allocate virtual memory pages using malloc and start paging while the required memory exceeds RSS?

Thanks

like image 297
Pirooz Avatar asked Feb 01 '10 20:02

Pirooz


1 Answers

You won't be able to allocate 100GB on a 32-bit machine and address it using regular pointers, which is what your code seems to use. The fact that machine 1 terminates the process when it hits approx 4GB and machine 2 doesn't strongly suggests that machine 2 is running a 64-bit OS.

like image 161
Timo Geusch Avatar answered Oct 22 '22 02:10

Timo Geusch