【问题标题】:C program memory usage - more memory reported than allocatedC 程序内存使用 - 报告的内存多于分配的内存
【发布时间】:2011-11-02 21:15:05
【问题描述】:

我有以下代码:

int main()
{
   char * str1 = (char*)malloc(101 * sizeof(char));
   for (int i=0; i<100; i++)
   {
      str1[i] = 'b';
   }
   str1[100] = 0;

   char * str2 = (char*)malloc(1001 * sizeof(char));
   for (int i=0; i<1000; i++)
   {
      str2[i] = 'a';
   }
   str2[1000] = 0;


   for (int i=0; i<7000; i++)
   {
      char * tmp = str2;
      str2 = (char*) malloc((strlen(str2) + strlen(str1) + 1) * sizeof(char));
      sprintf(str2, "%s%s", tmp, str1);
      free(tmp);
   }

   free(str1);
   free(str2);
}

运行时,任务管理器会报告以下内存使用情况: 程序开始 - 1056K , 程序结束 - 17,748K

据我所知,没有内存泄漏,我编译它时没有调试符号(发布模式)。

任何想法为什么会发生这种情况?

【问题讨论】:

标签: c memory


【解决方案1】:

我认为这是因为free 不必将内存返回给操作系统。它只是将它返回到空闲池,malloc 可以从中分配它。

【讨论】:

  • 当您分配的内存超过操作系统为您的程序指定的内存时,操作系统会增加可供您的程序使用的内存量。当您释放内存时,可用的数量不一定会减少。
  • 是的,此行为完全由任何给定主机上的 VMM 实现定义。 free() 所做的只是表明不再需要内存。这就是为什么对悬空指针进行操作会导致未定义行为的原因之一。
  • 嗯,这似乎与我在调试时注意到的行为一致......每次调用 malloc 时,mem 的使用量并没有增加,而是不时增加。
  • 我认为这也与 malloc 大小有关。如果我编写一个以相同大小执行 malloc/free 的程序,则不会发生任何事情。如果我在每次迭代时更改 malloc 大小,最后我会增加内存使用量。
【解决方案2】:

这可能是 malloc 如何从可用内存池中选择以满足 malloc 的人工制品。此外,TaskManager 和 top(用于 unix)之类的工具在提供进程使用的实际内存指示方面非常糟糕。每次我的一个客户给我一个最高输出并告诉我我的过程泄漏时,我都会畏缩,因为现在我必须证明它不是。

【讨论】:

  • 没错。任务管理器的输出非常不可靠。
【解决方案3】:

malloc是C标准库提供的内存管理函数。当您的程序调用 malloc 时,它不是直接从操作系统分配内存。 Malloc 实现通常具有一个内存池,它们将其划分为块以满足分配请求。当你调用 free 时,你只是把你的内存块还给这个内存池。

对 malloc 的重复调用最终会从标准库管理的内存池中分配所有内存。此时需要进行系统调用以从操作系统获取更多内存。在 linux 上这是 brk 系统调用,在 Windows 上无疑会有类似的东西。

Windows 中的 Task Manager 或 linux 中的 top 将报告操作系统已分配给您的进程的内存量。这通常会超过您的程序通过 malloc 分配的内存量。

如果你在 linux 上跟踪一个程序,你可以看到这些 malloc 和 brk 调用

ltrace -S <some program>
malloc(65536 <unfinished ...>
SYS_brk(NULL)                = 0x2584000
SYS_brk(0x25b5000)           = 0x25b5000
SYS_brk(NULL)                = 0x25b5000
<... malloc resumed> )       = 0x2584010

在这个例子中,我们尝试 malloc(65536),但是 malloc 系统没有足够的空闲内存来满足这个请求。所以它调用 brk() 系统调用从操作系统获取更多内存。此调用完成后,它可以恢复 malloc 调用并为程序提供它所请求的内存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 2015-12-28
    • 2013-02-23
    • 2014-12-11
    • 2016-11-24
    • 2016-02-16
    相关资源
    最近更新 更多