I'm writing an application which needs a lot of memory for caching purposes as I described he here. Now I'm playing around with some malloc / new constructions to figure out how I could realise it. I made a strange observation:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
while(1) {
char *foo = (char*)malloc(1024);// new char[1024];
if(foo == NULL) {
printf("Couldn't alloc\n");
fflush(stdout);
return 0;
}
}
return 0;
}
Why does that printf never be reached? If my system runs out of memory, malloc is said to return NULL, as it is explained here. But I always receive SIGKILL (I'm using linux...).
Yes. Malloc will return NULL when the kernel/system lib are certain that no memory can be allocated. The reason you typically don't see this on modern machines is that Malloc doesn't really allocate memory, but rather it requests some “virtual address space” be reserved for your program so you might write in it.
For some applications, the right thing to do is to shrink caches and try the malloc again. For some multithreaded programs, just waiting (to give other threads a chance to free memory) and retrying will work. For applications that need to be highly reliable, you need an application level solution.
We can also use the Malloc function to check for errors about memory allocation. When a malloc method finds itself unable to allocate memory, it usually returns NULL. You can also through an error message if the allocation got failed upon managing the pointers.
The calloc() function allocates memory for an array of nmemb elements of size bytes each and returns a pointer to the allocated memory. The memory is set to zero. If nmemb or size is 0, then calloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().
Linux, by default, usually uses an opportunistic memory allocation scheme, meaning the kernel will give you a valid address that won't be allocated until first use.
See:
According to those responses you can turn this feature off using echo 2 > /proc/sys/vm/overcommit_memory
.
From what I can tell, this is done under the assumption that you wont necessarily use all the memory that you allocate. I can't say that I personally ever allocate space that I don't touch at least once, so I'd be curious to know how this affects real life performance...
Regarding the SIGKILL failure, every malloc you call is still allocating some memory for each call. Eventually you will likely fill your memory with malloc overhead and thus evoke the fury of the out of memory kill feature. Whether this alone is the issue or if perhaps the overcommit policy still allocates some fraction of the requested space is a good question.
Usually, Linux will allocate as much (virtual) memory as you request, and only allocate physical memory for it when it's needed. If the system runs out of physical memory, then it starts killing processes to free some.
This means that malloc
will succeed unless the request is ludicrous, but your process (or some other) is likely to get killed as the memory is used.
For more details, see the manpage for malloc
, and its references:
By default, Linux follows an optimistic memory allocation strategy. This means that when
malloc()
returns non-NULL
there is no guarantee that the memory really is available. In case it turns out that the system is out of memory, one or more processes will be killed by the OOM killer. For more information, see the description of /proc/sys/vm/overcommit_memory and /proc/sys/vm/oom_adj inproc(5)
, and the kernel source file Documentation/vm/overcommit-accounting.
(And of course new
won't return null anyway unless you use the no-throwing version).
malloc
returns NULL
if requested allocation cannot be fulfilled. But maybe you should try allocating tons of space from heap.
See here.
On linux, the only way to get an error when calling malloc() is to disable memory-overcommiting. On regular linux systems, this is the only way for malloc() to return NULL. If an icecast process reaches that point, it's screwed anyway it won't be able to do anything meaningful: any source reads will fail (refbuf alloc), any log print will also fail (printf uses malloc too), so it might as well give up and call abort().
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With