通常fork实际上并不复制所有内存,而是使用"写入时复制",这意味着只要不修改内存,就会使用相同的页面.但是,为了避免以后没有足够的内存(如果进程写入内存)必须分配足够的内存.
这意味着在不允许过度使用内存的系统上从大型进程分叉,内存必须可用.因此,如果您有8 GB的进程分叉,那么至少在短时间内必须有16 GB.
有关其他解决方案,另请参见vfork和posix_spawn.
一些非常古老的系统(早期的unix),或者非常特殊的系统(无mmu的linux)或者非常蹩脚的系统(通过cygwin的windows)确实需要在fork上制作所有页面(“每个字节”)的完整副本,因此潜力就在那里。
现代 UNIX 内核不会复制所有进程内存,而是选择创建虚拟副本。虽然这仅涉及复制的一小部分(需要复制页表),但这仍然可能是许多兆字节并且需要大量时间。
所以答案是,一般来说是的,但大多数现代实现都使用硬件来制作快速虚拟副本,但即使该虚拟副本也不是免费的。
旧系统和一些现代系统都实现了特殊的 vfork() 调用,该调用具有一定的严格限制(尽管不如 vfork 的 POSIX 要求严格),但出于性能原因,请避免此复制。
给出一些实际数字,在我的 GNU/Linux 系统上,我可以每秒从 20MB 进程 fork+exit 1340 次,但在 2000MB 进程上每秒只能 fork+exit 235 次。这两种情况都是vfork+execve更快,这有点不直观,因为很多人认为“fork快”而“execve一定慢”。