Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我的c程序不能像应该的那样释放内存?_C_Macos_Unix_Memory - Fatal编程技术网

为什么我的c程序不能像应该的那样释放内存?

为什么我的c程序不能像应该的那样释放内存?,c,macos,unix,memory,C,Macos,Unix,Memory,我用c语言编写了一个程序,想看看它使用了多少内存,并注意到,在正常使用时,内存使用量会增加(在启动时,它使用了大约250k,现在是1.5mb)。好了,我释放了所有未使用的内存,一段时间后,应用程序使用的内存更少。有没有可能,释放的内存只是从“活动”内存转到“有线”内存或其他什么,所以在需要可用空间时释放? 顺便说一句,如果这很重要,我的机器在mac os x上运行。如何确定内存使用情况?您是否尝试使用查找潜在内存泄漏?这真的很容易。只需使用valgrind启动应用程序,运行它,然后查看结构良好的

我用c语言编写了一个程序,想看看它使用了多少内存,并注意到,在正常使用时,内存使用量会增加(在启动时,它使用了大约250k,现在是1.5mb)。好了,我释放了所有未使用的内存,一段时间后,应用程序使用的内存更少。有没有可能,释放的内存只是从“活动”内存转到“有线”内存或其他什么,所以在需要可用空间时释放?
顺便说一句,如果这很重要,我的机器在mac os x上运行。

如何确定内存使用情况?您是否尝试使用查找潜在内存泄漏?这真的很容易。只需使用
valgrind
启动应用程序,运行它,然后查看结构良好的输出。

如果您查看操作系统的内存使用情况,您可能会看到这种行为。释放的内存不会自动返回到操作系统,但通常会保留在进程中,并且可以稍后进行malloced。你看到的通常是记忆使用的最高点


正如Konrad Rudolph所建议的,使用从进程内部检查内存的方法来查找内存链接。

C库通常不会向操作系统返回“小”分配。相反,它会在下次使用
malloc
时保留内存


但是,许多C库将释放大的块,因此您可以尝试执行数兆字节的malloc,然后释放它。

在OSX上,如果您已经从OSX安装了开发人员工具,您应该能够使用MallocDebug.app(因为您可能很难找到OSX的valgrind端口)


/开发者/Applications/PerformanceTools/MallocDebug.app

我同意大家已经说过的话,但我只想补充一些针对os x的澄清意见:

首先,操作系统实际上使用
vm\u allocate
分配内存,它一次分配整个页面。正如其他人所说,由于这是有成本的,所以当您通过
free(3)
返回内存时,C库不会仅仅释放页面。具体来说,如果内存页中有其他分配,则不会释放它。目前,mac os x中的内存页为4096字节。页面中的字节数可以使用
sysctl(2)
或更简单的
getpagesize(2)
通过编程确定。您可以使用此信息优化内存使用


其次,用户空间应用程序不连接内存。通常情况下,内核会为关键数据结构连接内存。有线内存基本上是一种永远无法交换的内存,并且永远不会产生页面错误。如果由于某种原因,在有线内存页中生成了一个页面错误,内核将死机,您的计算机将崩溃。如果应用程序显著增加了计算机的有线内存,这是一个非常糟糕的迹象。这通常意味着您的应用程序正在做一些显著增加内核数据结构的事情,比如分配和不获取数百个子进程线程。(当然,这是一个一般性的说法……在某些情况下,这种增长是预期的,比如在开发虚拟主机或类似的东西时)。

除了其他人已经写过的内容之外:

malloc()从操作系统中分配较大的块,并在malloc()运行时将其分成较小的块。当空闲()时,工件首先进入空闲列表,以便在尺寸合适的情况下被另一个malloc快速重用。此时,它可能会与另一个空闲项合并,以形成更大的空闲块,以避免碎片(存在大量不同的算法,从自由列表到二进制大小的碎片再到散列等等)。 当释放的片段到达以便可以连接多个片段时,free()通常会这样做,但有时片段会保留下来,具体取决于malloc()和free()的大小和顺序。而且,只有当一个如此大的空闲块被创建后,它才会(有时)作为块返回到操作系统。但通常情况下,malloc()会根据分配/释放比率(许多启发式方法,有时还有编译或标记选项)把东西放在口袋里


请注意,没有一个malloc/free算法。有一大堆不同的实现(和文献)。高度依赖于系统、操作系统和库。

eeehm。。我刚刚启动activity monitor.app并查看了它使用了多少内存。我问的原因是monitor.app和类似的应用程序不能可靠地显示实际内存使用情况。Zan指出了其中一个原因。Valgrind是一个很棒的工具+1。mallocdebug.app似乎不允许网络连接,而且当我的应用程序处理网络请求时,很难看到它在请求后分配了多少内存