Recently I did some searching for a program that would induce low memory conditions on my linux box. I wanted to do some stress testing on a web app while the machine was low in memory. Unfortunately I couldn't find a decent program, so I wrote one! Since I've found that "tutorial" sites are very popular (I visit them myself daily), I thought posting this might be good for the blog. And what's good for the blog, is good for Ryan.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MEGABYTE 1024*1024
#define LOWMEMORY 30000
/*
* SUMMARY: Induce low memory conditions by allocating memory in 1 MB chunks and checking free memory until there is only LOWMEMORY KB of free memory left
* REQUIREMENTS: Must be run on a Linux machine, and the LOWMEMORY number should be in KB
* AUTHOR: Ryan Gerard, ryan dot gerard at gmail dot com
*/
int main(int argc, char *argv[]) {
void *myblock = NULL;
int count = 0;
int freeMem = 0;
//Allocate memory in 1 MB chunks as long as the free mem can be found and the free mem is greater than LOWMEMORY KB
while( (freeMem = getFreeMem()) != -1 && freeMem > LOWMEMORY)
{
myblock = (void *) malloc(MEGABYTE);
if (!myblock) break;
memset(myblock,1, MEGABYTE);
printf("Currently allocating %d MB\n",++count);
printf("Free mem is %d KB\n", freeMem);
}
//Print out amount of free memory left
printf("%d free memory left\n", getFreeMem());
exit(0);
}
/*
* Parse the output of 'vmstat' to determine the amount of free memory left on the system
*/
int getFreeMem()
{
FILE *readFile;
char string[256];
int cnt = 0;
int freeMem = -1;
//Output memory information to file tmpfile
system("vmstat -a 1 1 > tmpfile");
//Open the file for reading
if ( (readFile = fopen("tmpfile", "r")) != NULL )
{
//Get the third line of text from the file
while( fgets(string, 256, readFile) && cnt < 2 )
cnt++
cnt = 0;
char* token = strtok(string, " ");
while(token != NULL && cnt < 3)
{
token = strtok(NULL, " ");
cnt++;
}
//Convert to an integer to return
freeMem = atoi(token);
//Close the file
fclose(readFile);
}
return freeMem;
}