I'm reading about fork
and exec
for an exam, and my book says that whenever it is needed to run a new (different) process in unix systems, you would fork the current process followed by an execve
.
However, it also says that whenever fork
is called, the whole memory image of the parent is copied to the new process.
Then my question is: What if you have a process with a really big memory image, and you just want to run a new process? Isn't it a waste of resources to copy all the data from the parent process if you are just going to replace it immediately?
Usually the fork does not actually copy all the memory, but uses a "copy on write" which means that as long as the memory is not modified the same pages are used. However, to avoid not having enough memory later on (should the process write to the memory) enough memory must be allocated.
This means that forking from large process on systems that do not allow overcommitting memory the memory must be available. So, if you have a 8 GB process forking, then for at least a short period of time 16 GB must be available.
See also vfork and posix_spawn for other solutions.
Some systems that are either very old (early unix), or very special (mmu-less linux) or verfy crappy (windows via cygwin) do need to make a full copy of all pages ("every byte") on fork, so the potential is there.
Modern unix kernels do not copy all the process memory, instead chosing to make a virtual copy. While this involves only a fraction of the copying (page tables need to be copied), this can still be many megabytes and take substantial time.
So the answer is, yes in general, but most modern implementations use hardware to make a fast virtual copy, but even that virtual copy isn't free.
Both old and some modern systems implement a special vfork() call which has somewhat strict limitations (although less strict than the POSIX requireemnts for vfork) but avoid this copy, for performance reasons.
To give some actual numbers, on my GNU/Linux system, I can fork+exit 1340 times per second from a 20MB process, but only 235 times/s on a 2000MB process. In both cases it is faster to vfork+execve, which is somewhat unintuitive, because many people think "fork is fast" and "execve must be slow".
No memory copy is made unless one of the process modified the memory, in which case the page will be copied, and if you are calling exec() in the child process right after fork() is called, no copy is made.
Actually I think to make sure exec() is always called before the father process ever write to memory, the child process always run first.
I think you can find this in Advanced Programming in the UNIX