2011-03-25 54 views
23

我知道當我在Linux中調用exec()系統調用之一時,它將用新映像替換當前正在運行的進程。因此,當我分叉一個新流程並運行exec()時,孩子將被替換爲新流程。exec()更改程序映像後,malloc會出現什麼情況?

從堆中分配的任何內存會發生什麼?假設我想解析任意數量的命令並將其發送到exec()。爲了保持這個任意數字,我可能不得不在一定程度上分配內存,因爲我認爲我無法正確使用靜態大小的數組,所以我可能會使用malloc()或其他等價物。

我需要保持這個內存分配,直到我叫exec(),但exec()永遠不會返回。

內存是否被操作系統回收?

+0

順便說一句,這是一個非常類似的問題http://stackoverflow.com/questions/3617332/what-happens-with-memory-usage-after-exec – sharptooth 2011-03-25 08:01:45

回答

18

當您撥打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()時,內存映射不會被保留,所以這個內存也被回收。

+0

這並不能解釋堆發生了什麼。好的,數據段被覆蓋,但這意味着堆被破壞,不會重置。 – sharptooth 2011-03-25 07:21:10

+0

堆是數據段。在一個簡單的實現中,'malloc()'會使用'brk()'來增長數據段並獲得更多的內存。當數據段被覆蓋時,其大小也會被重置,並且內存被有效釋放。 – 2011-03-25 07:27:32

+0

我認爲「堆腐敗」通常意味着malloc()使用的堆中的數據結構被破壞(例如,當指針被釋放兩次時)。當數據段被覆蓋時,沒有什麼可以被破壞了。 – 2011-03-25 07:29:11

3

整個堆分配的內存以及所有用於管理它的邏輯malloc 是過程映像的一部分,它將取代 。它只是消失,就你的過程 有關。該系統當然可以恢復並回收它。

相關問題