I'm getting the titular error:
mcfork(): Unable to fork: Cannot allocate memory
after trying to run a function with mcapply, but top
says I'm at 51%
This is on an EC2 instance, but I do have up-to-date R.
Does anyone know what else can cause this error?
Thanks,
-N
The issue might be exactly what the error message suggests: there isn't enough memory to fork and create parallel processes.
R essentially needs to create a copy of everything that's in memory for each individual process (to my knowledge it doesn't utilize shared memory). If you are already using 51% of your RAM with a single process, then you don't have enough memory to create a second process since that would required 102% of your RAM in total.
Try:
registerDoMC(2)
, for example, will set the number of parallel threads to 2 (if you are using the doMC
parallel backend). rm(my_big_object)
)R function mcfork
is only a wrapper to the syscall fork
(BtW, the man page says, that this call is itself a wrapper to the clone
)
I created a simple C++ program to test fork
's behaviour:
#include <stdio.h> #include <unistd.h> #include<vector> int main(int argc, char **argv) { printf("--beginning of program\n"); std::vector<std::vector<int> > l(50000, std::vector<int>(50000, 0)); // while (true) {} int counter = 0; pid_t pid = fork(); pid = fork(); pid = fork(); if (pid == 0) { // child process int i = 0; for (; i < 5; ++i) { printf("child process: counter=%d\n", ++counter); } } else if (pid > 0) { // parent process int j = 0; for (; j < 5; ++j) { printf("parent process: counter=%d\n", ++counter); } } else { // fork failed printf("fork() failed!\n"); return 1; } printf("--end of program--\n"); while (true) {} return 0; }
First, the program allocates about 8GB data on heap. Then, it spawns 2^2^2 = 8 children via fork call and waits to be killed by the user, and enters an infinite loop to be easy to spot on task manager.
Here are my observations:
/proc/sys/vm/overcommit_*
proc files.Memory fragmentation issue
You should not be concerned about any layer of memory fragmentation with respect to fork. R's memory fragmentation doesn't apply here, because fork operates on virtual memory. You shouldn't worry about fragmentation of physical memory, because virtually all modern operating systems use virtual memory (which consequently enables them to use swap). The only memory fragmentation that might be of issue is a fragmentation of virtual memory space, but AFAIK on Linux virtual memory space is 2^47 which is more than huge, and for many decades you should not have any problems with finding a continuous regions of any practical size.
Make sure you have more swap then physical memory, and as long as your computations don't actually need more memory then you have in RAM, you can mcfork
them as much as you want.
Or, if you are willing to risk stability (memory starvation) of the whole system, try echo 1 >/proc/sys/vm/overcommit_memory
as root on linux.
Or better yet: (more safe)
echo 2 >/proc/sys/vm/overcommit_memory echo 100 >/proc/sys/vm/overcommit_ratio
You can read more about overcommiting here: https://www.win.tue.nl/~aeb/linux/lk/lk-9.html
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