5

For my course project on Linux Kernel, I need to simulate a situation where there is a lot of page swapping due to low memory.

I want to write a program which needs a lot of physical memory, so that pages accessed by this program have to be swapped in and out multiple times.

VAndrei
  • 5,420
  • 18
  • 43
Neo
  • 3,465
  • 5
  • 26
  • 37
  • use calloc. See these threads: http://superuser.com/questions/278855/a-linux-program-that-uses-memory and http://stackoverflow.com/questions/4383059/malloc-memory-questions – RaGe Apr 24 '15 at 19:35

2 Answers2

5

Of, so first of all you really need to allocate a buffer larger than your RAM size. I hope you run on a 64bit OS or you have PAE enabled. If have let's say 4GB of RAM, you need something like:

double* pBigArray = (double*)malloc(sizeof(double) * 536870912); 
// You actually need more than that. This is just 4GB.

Now, just having an array, larger than your RAM size is not enough. It matters how you access it. If you just read elements consecutively, the hardware prefetchers in your CPU will bring some of the data your program will read, into the cache.

To generate many page faults, you need to read from an address that is not in the RAM.

To do that this is a simple method, by reading from the array randomly:

double lfBigChecksum = 0.0;
while (true)
{
   int iIndex = rand() % BUFFER_SIZE;
   lfBigChecksum += pBigArray[iIndex];
}

If you have an array of 8GB and 4GB of RAM, half of the reads will be page faults (and served from the swap space in the hard disk).

VAndrei
  • 5,420
  • 18
  • 43
  • Good answer. Just curious, but why allocate "doubles" instead of single byte chars? He could just as easily write `malloc(4294967296ULL);` – selbie Apr 25 '15 at 17:06
  • Well, because a cache line fits less doubles (only 8) than chars (64) and the chances of hitting same cache line are reduced. Other than that, there's no real reason. – VAndrei Apr 25 '15 at 17:08
  • 1
    Also, if he's running 32-bit OS, he'd wouldn't be able to allocate 4GB. `malloc` would shrug and return NULL immediately. He could malloc in a loop of say 100MB until malloc returns NULL. And if needed, he could have several instances of his program running to force page-swapping on 32-bit. – selbie Apr 25 '15 at 17:08
  • That's true. Hopefully he has 64bit or PAE enabled. If not, what you propose seems a good solution. – VAndrei Apr 25 '15 at 17:10
  • One thing in the above code to account for. `rand()` only returns a value between **0-0x7fffffff**. I guess that implicitly works itself out if if he uses a double array instead of a char array like I was thinking. But he could say this in the loop: `size_t iIndex = rand()|(((size_t)rand())<<8) % BUFFER_SIZE;` – selbie Apr 25 '15 at 17:21
  • @VAndrei How do you identify `iIndex` that cause page-fault from those that does not? Is there a time limit to be consider time caused by cpu-stall due to page-fault ? – Fopa Léon Constantin Aug 15 '16 at 10:23
  • @FopaLéonConstantin you could measure the transaction time with a high resolution counter. A page fault would have high latency. Do this for all transactions and then make a histogram to determine if there is an observable threshold. – VAndrei Jan 24 '17 at 16:48
-3

You can eat up a ton of memory just by dynamically allocating tons of space and not using it. IE in C++ you can do

int *foo = new int[10000000];

Which will just eat up 40MB (assuming your ints are 4 btyes) and do nothing with it. Do this a couple of times (you may need to spread it out over several processes) and you'll eat up your RAM fast.

David says Reinstate Monica
  • 19,209
  • 22
  • 79
  • 122
  • [David Grinberg](http://stackoverflow.com/users/1305516/david-grinberg) From my understanding, unless I use the allocated memory, physical memory wont be affected (only virtual memory is allocated). Is this not the case? – Neo Apr 24 '15 at 14:44
  • @Venkatesh you are "using" it. We're using dumb pointers in C++, its not smart enough to tell if you are _really_ using it. Simply by declaring it you are using the memory. You can try it out yourself - check your memory before, then run this, then check memory again while its running (make sure to put a `while(true)` at the end). – David says Reinstate Monica Apr 24 '15 at 14:47
  • 1
    I am using C language. And I allocated dynamic memory using `int *foo = malloc(10000000);`. However my RSS is just 356 KB (as reported by `/proc/$pid/status`). – Neo Apr 24 '15 at 14:52