我知道当我在Linux中调用其中一个exec()
系统调用时,它将使用新映像替换当前正在运行的进程。因此,当我分叉一个新进程并运行exec()
时,子进程将替换为新进程。
我从堆中分配的内存会发生什么变化?假设我想解析任意数量的命令并将其发送到exec()
。为了保持这个任意数字,我可能不得不在某些时候分配内存,因为我认为我不能正确使用静态大小的数组,所以我可能会使用malloc()
或类似的东西。
我需要保留这个内存,直到我调用exec()
,但exec()
永远不会返回。
操作系统是否回收了内存?
答案 0 :(得分:25)
当您致电fork()
时,会创建一个调用流程的副本。这个子进程(几乎)与父进程完全相同,即malloc()
分配的内存被保留,您可以自由地阅读或修改它。但是,父进程不会看到修改,因为父进程和子进程是完全分开的。
当您在孩子中呼叫exec()
时,子流程将被新流程替换。来自execve(2):
execve() does not return on success, and the text, data, bss, and stack
of the calling process are overwritten by that of the program loaded.
通过覆盖data
段,exec()
调用有效地回收了malloc()
之前分配的内存。
父进程不受所有这些影响。假设您在调用fork()
之前在父进程中分配了内存,则内存在父进程中仍然可用。
编辑:malloc()
的现代实现使用匿名内存映射,请参阅mmap(2)。根据execve(2),内存映射不会在exec()
调用中保留,因此也会回收此内存。
答案 1 :(得分:4)
整个堆 - 分配内存,以及所有逻辑malloc 用来管理它 - 是过程图像的一部分 更换。就你的过程而言,它就会消失 关心。当然,该系统可以恢复并回收它。