我收到了名义错误:
mcfork(): Unable to fork: Cannot allocate memory
尝试使用mcapply运行函数后,但top
说我是51%
这是在EC2实例上,但我确实有最新的R.
有谁知道还有什么可能导致此错误?
谢谢,
-N
答案 0 :(得分:15)
问题可能正是错误消息所暗示的:没有足够的内存来分叉和创建并行进程。
R本质上需要为每个单独的进程创建内存中的所有内容的副本(据我所知,它不使用共享内存)。如果您已经在一个进程中使用了51%的RAM,那么您没有足够的内存来创建第二个进程,因为这将需要102%的RAM。
尝试:
registerDoMC(2)
例如,将设置并行线程数为2(如果使用doMC
并行后端)。 rm(my_big_object)
)答案 1 :(得分:5)
R函数mcfork
只是系统调用fork
的包装器(BtW,手册页说,这个调用本身就是clone
的包装器)
我创建了一个简单的C ++程序来测试fork
的行为:
#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;
}
首先,程序在堆上分配大约8GB的数据。 然后,它通过fork调用产生2 ^ 2 ^ 2 = 8个子节点并等待被用户杀死,并进入无限循环以便在任务管理器上找到。
以下是我的观察:
/proc/sys/vm/overcommit_*
proc文件来更改此内容。内存碎片问题
您不应该担心与fork 相关的任何内存碎片层。 R的内存碎片在这里不适用,因为fork在虚拟内存上运行。您不应该担心物理内存的碎片,因为几乎所有现代操作系统都使用虚拟内存(因此可以使用虚拟内存)。可能存在问题的唯一内存碎片是虚拟内存空间的碎片,但是Linux虚拟内存空间上的AFAIK是2 ^ 47,这是巨大的,并且几十年来你不应该找到连续的区域任何实际尺寸。
确保你有更多的交换然后物理内存,并且只要你的计算实际上不需要更多的内存然后你有RAM,你可以mcfork
尽可能多的。
或者,如果您愿意冒整个系统的稳定性(内存饥饿),请在linux上以root身份尝试echo 1 >/proc/sys/vm/overcommit_memory
。
或者更好:(更安全)
echo 2 >/proc/sys/vm/overcommit_memory
echo 100 >/proc/sys/vm/overcommit_ratio
您可以在此处详细了解过度使用:https://www.win.tue.nl/~aeb/linux/lk/lk-9.html
答案 2 :(得分:1)
我有同样的错误,同时使用插入符号在64 GB内存的系统上训练rpart模型,并在7核心机器上使用6核进行并行处理。改为5核心,问题就出现了。
library(doMC)
registerDoMC(5)
答案 3 :(得分:1)
我现在遇到了类似的问题。我不会声称知道正确的答案。上述两个答案都提出了可能有效的行动方案,特别是如果您的叉子同时对内存产生额外的写入要求。但是,我一直认为其他东西可能是困难的根源。内存碎片。请参阅https://raspberrypi.stackexchange.com/questions/7856/log-says-i-cant-allocate-memory-but-i-have-more-than-half-of-my-memory-free以了解类似Unix用户看到空闲内存但由于内存碎片而导致内存不足错误的情况的讨论。这似乎是R的罪魁祸首,特别是因为R喜欢连续的RAM块。另外,?Memory-limits
每个WHERE p.parent_id IS NOT NULL
的要求应该是地址空间而不是RAM本身 - 所以这可能是不正确的(特别是在64位机器上)YMMV。
答案 4 :(得分:1)
想要使用RStudio等GUI的人的注意事项。
如果要利用并行处理,建议不要使用GUI,因为它会中断代码和GUI程序之间的多线程进程。以下是关于R的<{1}}包帮助手册的摘录
多核功能最初由Simon Urbanek编写并包含在R 2.14.0中的并行包中,它提供了在具有多个内核或处理器的机器上并行执行R代码的功能,使用系统fork调用来生成副本目前的过程。
多核功能以及寄存器DoMC不应在GUI环境中使用,因为多个进程共享同一个GUI。
我在使用RStudio运行我的程序时通过禁用registerDoMC
解决了OP遇到的类似错误。多处理最适合基础R.希望这会有所帮助。