问题描述
由于父进程正在使用大量内存,因此在某些内核过量使用策略配置下,fork
可能会因ENOMEM
的errno
失败.即使子进程只能像这样的低内存消耗程序.
As the parent process is using huge mount of memory, fork
may fail with errno
of ENOMEM
under some configuration of kernel overcommit policy. Even though the child process may only exec
low memory-consuming program like ls.
为澄清问题,将/proc/sys/vm/overcommit_memory配置为2时,(虚拟)内存的分配限制为SWAP + MEMORY * ration(default to 50%)
.进程分叉时,由于使用了COW,因此不会复制虚拟内存.但是内核仍然需要分配虚拟内存空间.打个比方,fork就像malloc(虚拟内存空间大小)一样,它不会分配物理内存,而写入共享内存将导致虚拟内存的副本,并且分配了物理内存.如果将overcommit_memory配置为2,则由于虚拟内存空间分配,fork可能会失败.
To clarify the problem, when /proc/sys/vm/overcommit_memory is configured to be 2, allocation of (virtual) memory is limited to SWAP + MEMORY * ration(default to 50%)
.When a process forks, virtual memory is not copied thanks to COW. But the kernel still need to allocate virtual memory space. As an analogy, fork is like malloc(virtual memory space size) which will not allocate physical memory and writing to shared memory will cause copy of virtual memory and physical memory is allocated. When overcommit_memory is configured to be 2, fork may fail due to virtual memory space allocation.
在以下情况下,是否可以fork
不继承父进程的虚拟内存空间的进程?
Is it possible to fork
a process without inherit virtual memory space of parent process in the following conditions?
-
如果子进程在
fork
,如果子进程未调用exec
并且不会使用父进程中的任何全局或静态变量.例如,子进程只是做一些日志记录然后退出.
if the child process doesn't call exec
and will not using any global or static variable from parent process. For example, the child process just do some logging then quit.
推荐答案
否,这是不可能的.您可能对 vfork(2)感兴趣,而我对不推荐.还要查看 mmap(2)及其MAP_NORESERVE
标志.但是内核使用了复制时复制技术,因此您几乎可以胜任不会使RAM消耗翻倍.
No, it is not possible. You might be interested by vfork(2) which I don't recommend. Look also into mmap(2) and its MAP_NORESERVE
flag. But copy-on-write techniques are used by the kernel, so you practically won't double the RAM consumption.
我的建议是具有足够的交换空间,以免受到此类问题的困扰.因此,将计算机设置为具有比最大的运行进程更多的可用交换空间.您始终可以创建一些临时交换文件(例如,先按dd if=/dev/zero of=/var/tmp/swapfile bs=1M count=32768
然后按mkswap /var/tmp/swapfile
),然后将其添加为临时交换区(swapon /var/tmp/swapfile
),然后将其删除(swapoff /var/tmp/swapfile
和rm /var/tmp/swapfile
),当您不再需要它时.
My suggestion is to have enough swap space to not being concerned by such an issue. So setup your computer to have more available swap space than the largest running process. You can always create some temporary swap file (e.g. with dd if=/dev/zero of=/var/tmp/swapfile bs=1M count=32768
then mkswap /var/tmp/swapfile
) then add it as a temporary swap zone (swapon /var/tmp/swapfile
) and remove it (swapoff /var/tmp/swapfile
and rm /var/tmp/swapfile
) when you don't need it anymore.
我不喜欢内存过量使用,并且我将其禁用(通过 proc(5)). YMMV.
I dislike memory overcommitment and I disable it (thru proc(5)). YMMV.
这篇关于是否可以在不继承父进程的虚拟内存空间的情况下派生一个进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!