I'm trying to initialize as much memory as possible (all of free memory), than sleep for 10 seconds and free it up. Calloc initializes it and it goes to a bit over 7800 MB, out of 8GB that I have, so I think it does the job, but the problem begins when (as long as I was reading forums and stuff) the OOM killer comes and kills it. So the process get's killed instead of calloc returning NULL. Is there any fix to that? How to stop it right before killing or how to return NULL when it runs out of memory?
int main() {
int *pointer;
int megabajti=1048576; //MB
int velikost_strani=4096; //page size
long long int i=0;
while(1)
{
pointer=calloc(velikost_strani,sizeof(int));
printf("Trenutno alociram %lld MB\n",i*velikost_strani*sizeof(int)/megabajti);
if(pointer==NULL)
{
printf("Max velikost je %lld MB\n",i*velikost_strani*sizeof(int)/megabajti);
free(pointer);
sleep(10);
}
++i;
}
return 0;
}
Generally, malloc()
and friends will not return NULL
only because you are out of physical RAM. They normally don't even know how much physical RAM you have, and will just try to get more from the OS, usually using mmap()
(or brk()
, but that's just a wrapper for mmap()
).
mmap()
, too, will not return failure just because you're out of physical RAM, but will try to use virtual memory. This is common across UNIX systems, and it's generally not possible to work directly with physical memory instead of virtual memory. The OOM-killer is just Linux' specific implementation of what happens when virtual memory cannot handle the demand for backing store. One method to make the OOM-killer go away is to allocate more swap space (for this and similar reasons, I find that it often is a good idea to keep a lot of swap space around).
The most common case where mmap()
and malloc()
will return failure is when they cannot handle the allocation for internal reasons, such as being out of virtual address space (which is pretty rare on 64-bit systems).
That being said, there exist mechanisms for dealing more directly with physical RAM if you want to avoid the potential complexities of virtual memory. One POSIX-defined mechanism is mlock()
, which will pin a certain amount of allocated RAM to physical pages, which is usually done to avoid the performance and/or security implications of swapping. It is restricted to the superuser and will usually only allow to lock a small amount of memory in total, however. See its manpage for details.
On Linux, you can also tweak the overcommit behavior. I have to admit I've never tried it myself, but behavior #2 (as documented in the link) seems to promise some kind of behavior similar to what you seem to be looking for.
None of these mechanisms are "ordinary", however, so if you're looking for a way to limit your allocations to physical memory in a way that is portable and reproducible on systems that you don't personally manage, you're probably out of luck, quite simply.