【问题标题】:Why does my c program not free memory as it should?为什么我的 c 程序没有按应有的方式释放内存?
【发布时间】:2010-10-01 15:58:13
【问题描述】:

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

【问题讨论】:

    标签: c macos unix memory


    【解决方案1】:

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

    【讨论】:

    • eeehm .. 我刚刚启动了 activity monitor.app 并查看了它使用了多少内存。
    • 我问的原因是 monitor.app 和类似的应用程序不能可靠地显示真实的内存使用情况。 Zan 指出了其中一个原因。
    • Valgrind 是一个很棒的工具 +1。
    【解决方案2】:

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

    正如 Konrad Rudolph 建议的那样,使用从进程内部检查内存的东西来查找内存链接。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        在 OSX 上,如果您从 OSX 安装了开发者工具,您应该能够使用 MallocDebug.app(因为您可能无法找到 OSX 的 valgrind 端口)。

        /Developer/Applications/PerformanceTools/MallocDebug.app

        【讨论】:

        • mallocdebug.app 似乎不允许网络连接,而且当我的应用程序处理网络请求时,很难看到它在请求后分配了多少内存
        【解决方案5】:

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

        首先,操作系统实际上使用vm_allocate 分配内存,它一次分配整个页面。因为与此相关的成本,就像其他人所说的那样,当您通过free(3) 返回内存时,C 库不只是释放页面。具体来说,如果内存页内还有其他分配,则不会被释放。当前内存页面在 mac os x 中为 4096 字节。一页中的字节数可以通过sysctl(2) 或者更简单的getpagesize(2) 以编程方式确定。您可以使用此信息来优化您的内存使用。

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

        【讨论】:

          【解决方案6】:

          除了其他人已经写的:

          malloc() 从操作系统分配更大的块,并在 malloc() 时将其分成更小的块。当 free()ing 时,该部分首先进入一个空闲列表,以便在大小合适的情况下由另一个 malloc 快速重用。此时它可能会与另一个空闲项合并,以形成更大的空闲块,以避免碎片(那里存在一大堆不同的算法,从 freeLists 到二进制大小的片段到散列等等)。 当释放的片段到达以便可以连接多个片段时,free() 通常会这样做,但有时,片段会保留,这取决于 malloc() 和 free() 的大小和顺序。此外,只有在创建了这样一个大的空闲块时,它才会(有时)作为一个块返回给操作系统。但通常,malloc() 将东西放在口袋里,取决于分配/空闲比率(许多启发式方法,有时编译或标记选项通常可用)。

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

          【讨论】:

            猜你喜欢
            • 2015-06-14
            • 2011-05-25
            • 1970-01-01
            • 1970-01-01
            • 2021-10-03
            • 2021-08-08
            • 2019-10-09
            • 2018-11-08
            相关资源
            最近更新 更多