malloc和free的复杂性

3

我有两个相关的问题,因此在这个单一的线程中提出。

问题1:如何确认我的操作系统是否会自动清除未释放(使用malloc分配的)内存 when a program terminates?我使用gcc-4.5.2的Ubuntu 11.04(32位)

根据Steven Summit的教程页面(在这里),"释放未使用的内存(malloc'ed)是一个好主意,但这不是强制性的。当您的程序退出时,它分配但未释放的任何内存应该自动释放。如果您的计算机由于您的程序忘记释放而某种方式“丢失”内存,那就说明您的操作系统存在问题或缺陷"

问题2:假设foo.c mallocs了B字节的内存。稍后,foo.c释放了这些B字节的内存位置并将其返回给操作系统。现在我的问题是,那些特定的B字节内存位置能否在当前实例中被重新分配给foo.c(由操作系统)或者直到其当前实例终止才能将这些B字节分配给foo.c?

编辑:我建议每个阅读我的问题的人都去阅读类似问题的答案在这里在这里。这两个答案都详细解释了malloc()和free()的交互和工作,而不使用非常晦涩的术语。要了解内核使用的内存管理工具(例如brk(),mmap())和C编译器使用的内存管理工具(例如malloc(),free())之间的区别,请务必阅读this

4个回答

2

现代大多数操作系统会回收已分配的内存,所以您不必担心这个问题。

操作系统并不知道您的应用程序/程序是否泄漏了内存,它只是在进程完成后回收分配给进程的内存。

是的,释放的内存可以被重复使用(如果需要),并且重用可以发生在同一时间段内。


有没有实际的方法来确认这一点,比如我可以制作一个测试软件或者直接使用? - Abhinav
@Abhinav:幸运的是,这种开销是不必要的。你只需要参考目标操作系统的文档,它应该会记录行为。 - Alok Save
@Abhinav,确认哪个部分?你无法在不对操作系统进行仪器化的情况下确认操作系统正在回收进程内存,这将会减慢其内存管理速度,并且在具有统一页面缓存的现代操作系统中,这将非常难以解密。对于进程内存重用,请查看http://valgrind.org/。 - geekosaur

2
当一个进程通过终止信号(例如SIGSEGV)或通过_exit(2)系统调用(从main返回时也会调用该系统调用)结束时,所有进程资源都将被内核释放。特别是,进程地址空间,包括使用mmap(2)分配的堆内存(或者使用sbrk(2)系统调用(由malloc库函数使用)分配的堆内存),都会被释放。
当然,free库函数通常将被释放的内存区域重新分配给后续对malloc的调用,或者(偶尔,对于大内存区域)使用例如munmap(2)系统调用将一些大的内存块释放给内核。
要了解进程1234的内存映射更多信息,请顺序读取/proc/1234/maps伪文件(或从进程内部读取/proc/self/maps)。/proc文件系统是查询内核有关进程信息的首选方式。(还有/proc/self/statm/proc/self/smaps等许多有趣的事情)。 freemalloc的详细行为取决于实现。你应该将malloc视为获取堆内存的一种方式,并将free视为指示以前用malloc分配的区域无用,然后系统(即标准C库+内核)可以对其进行任何操作。
使用valgrind查找内存泄漏错误。您还可以考虑使用Boehm的保守垃圾收集器,即使用GC_malloc而不是malloc,并且不必手动释放内存。

感谢您的满意的答案。我想,只要foo.c程序在运行,/proc/foo/目录就会存在。对吧?那么,在这种情况下,我怎样才能找到相应的映射文件呢?虽然我确实检查了一些正在运行的pid的映射文件(例如chrome),它向我抛出了一堆惊人的信息。我感到十分惊讶。 :) - Abhinav
我不确定是否理解你的问题(请记住,可执行文件和进程不同;一个给定的程序有一个可执行文件,例如你的shell的/bin/bash,但可以在多个进程中运行)。/proc/1234/仅存在于进程1234存在的时间内。(它是一个伪文件,不在磁盘上,因此读取它很快)。从该进程内部,/proc/self/是指向它的符号链接。 - Basile Starynkevitch
赞 Valgrind 和 Boehm 的链接。 - Abhinav

1

问题1:您只需要假设操作系统正常运行。

问题2:字节被重新分配给foo.c没有任何问题,这取决于内存分配例程的工作方式。


1

第二个链接有一个非常棒的答案。(https://dev59.com/eXNA5IYBdhLWcg3wBpHs#1119334) - Abhinav
有一种思想认为,退出程序时不应该释放内存 - 主张是这就像清理一个即将被拆除的房子一样,是完全浪费时间和精力的。我并不完全同意,但无法反驳这个观点 :) - mattnz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接