exec()更改程序映像后malloc的内存会发生什么变化?
我知道当我在Linux中调用其中一个exec()
系统调用时,它将使用新映像替换当前正在运行的进程。 因此,当我分叉一个新进程并运行exec()
,子进程将被替换为新进程。
我从堆中分配的内存会发生什么变化? 假设我想解析任意数量的命令并将其发送到exec()
。 为了保持这个任意数字,我可能不得不在某些时候分配内存,因为我认为我不能正确使用静态大小的数组,所以我可能会使用malloc()
或类似的东西。
我需要保持这个内存分配,直到我调用exec()
,但exec()
永远不会返回。
内存是否被操作系统回收?
调用fork()
,会创建调用进程的副本。 这个子进程(几乎)与父进程完全相同,即malloc()
分配的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()
之前分配的malloc()
。
父进程不受所有这些影响。 假设您在调用fork()
之前在父进程中分配了内存,则内存在父进程中仍然可用。
编辑: malloc()
现代实现使用匿名内存映射,请参阅mmap(2)。 根据execve(2),内存映射不会在exec()
调用中保留,因此也会回收此内存。
整个堆 – 分配的内存以及malloc用于管理它的所有逻辑 – 都是被替换的过程映像的一部分。 就你的过程而言,它就会消失。 当然,该系统可以恢复并回收它。