Ani*_*mar 9 linux fork virtual-memory memory-overcommitment
父进程在尝试分叉子进程时失败,并且errno = 12(内存不足).父进程在Linux 3.0内核上运行 - SLES 11.在分叉子进程时,父进程已经占用了大约70%的RAM(180GB/256GB).这个问题有解决方法吗?
该应用程序是用C++编写的,用g ++ 4.6.3编译.
SKi*_*SKi 12
也许在您的系统中阻止了提交虚拟内存.
如果被阻止,则虚拟内存不能大于物理RAM +交换的大小.如果允许,则虚拟内存可以大于RAM + swap.
当您的进程分叉时,您的进程(父进程和子进程)将具有2*180GB的虚拟内存(如果您没有交换则太多).
所以,通过这种方式允许过度提交:
echo 1 > /proc/sys/vm/overcommit_memory
Run Code Online (Sandbox Code Playgroud)
如果子进程立即执行,它应该有所帮助,或者在父进程写入太多内存之前释放已分配的内存.所以,要小心,如果两个进程都继续使用所有内存,则内存杀手可能会起作用.
proc(5)的手册页说:
的/ proc/sys目录/ VM/overcommit_memory
此文件包含内核虚拟内存记帐模式.值是0:启发式过量使用(这是默认值)1:总是过量使用,从来不检查2:经常检查,从不过量使用
在模式0中,不检查具有MAP_NORESERVE的mmap(2)调用,并且默认检查非常弱,导致获得进程"OOM-killed"的风险.在Linux 2.4下,任何非零值都意味着模式1.在模式2(从Linux 2.6开始可用)中,系统上的总虚拟地址空间限制为(SS + RAM*(r/100)),其中SS是交换空间,RAM是物理内存的大小,r是文件/ proc/sys/vm/overcommit_ratio的内容.
更多信息:在SLES中过度使用内存
fork-ing 需要资源,因为它是在写入时复制进程的可写页面。再次阅读fork(2)手册页。
您至少可以提供一个巨大的临时交换文件。您可以(在某些具有足够空间的文件系统上)创建一个巨大的$SWAPFILE文件
dd if=/dev/zero of=$SWAPFILE bs=1M count=256000\n mkswap $SWAPFILE\n swapon $SWAPFILE\nRun Code Online (Sandbox Code Playgroud)\n\n否则,您可以以不同的方式设计您的程序,例如mmap-ing 一些大文件(并munmap在 fork 之前 -ing 它,并mmap在 fork 之后再次 -ing 它),或者更简单地从程序的开头开始 -ed popenshell,或一个 -ed 或明确地在其之间p2open添加-s (可能多路复用调用 \xc3\xa0 la也很有用),然后向其发出命令。pipepoll
如果我们了解您的程序正在做什么,为什么它消耗这么多内存,以及它为什么和什么是分叉的,也许我们可以提供更多帮助......
\n\n阅读高级 Linux 编程了解更多信息。
\n\n如果您fork只是为了gdb显示回溯,请考虑更简单的替代方案,例如最近的 GCC 的 libbacktrace或Wolf 的 libbacktrace ...