当内核创建两个代码段相同的进程时,内核是否真的将代码复制到两个进程的虚拟地址空间?换句话说,如果我创建同一个程序的两个进程,在内存中,我们有两个程序副本还是只有一个副本?
显然,它可能取决于实现,但我在传统的 Unix 操作系统中询问。
内核是否真的将代码复制到两个进程的虚拟地址空间?
文本段将被映射(而不是复制)到每个进程的虚拟地址空间,但将引用相同的物理空间(因此内核在内存中只有一份文本副本)。
data 和 bss 段也将映射到每个进程的虚拟地址空间,但这些将在每个进程中创建。在进程启动时,来自可执行文件的数据和 bss 段的数据将被映射/复制到进程的虚拟内存中;如果它不是从头开始复制的,那么一旦进程开始写入数据,进程就会获得自己的私有副本。
显然,共享内存和 mmap 内存是在进程启动后处理的。共享内存总是在进程之间共享;这就是它存在的理由。mmap 会发生什么取决于使用的标志,但它也经常被共享。
现代操作系统将使用Copy-on-Write来避免重复页面,直到它们实际更新。请注意,在许多系统(包括 Linux)上,这可能会导致过度使用,如果每个进程决定修改未复制的页面,操作系统实际上没有足够的 RAM 来处理所需的所有复制。