这个程序中的常驻内存行为?

时间:2014-05-06 11:16:13

标签: c++ memory-management memory-leaks operating-system

我正在处理常驻内存增加问题。 为了模拟我编写了一个实际模拟我的问题的代码片段。

#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <malloc.h>
using namespace std;

int main()
{
    int  count = 0;
    char szCmd[128];

    system("> result_top.txt");

    while (count < 10)
    {
        sprintf(szCmd, "echo \"\nRound %d\n\" >> result_top.txt", count);
        system(szCmd);

        system("top -b -n 1 -p `pgrep a.out` | tail -4 >> result_top.txt");

        int **t = new int*[100000];

        for(long i = 0; i < 100000; i++)
        {
            t[i] = new int();
        }

        system("top -b -n 1 -p `pgrep a.out`| tail -4 >> result_top.txt");

        for(long i = 100000 - 1; i >= 0; i--)
        {
            delete t[i];
        }

        delete [] t;

        sleep(5);

        system("top -b -n 1 -p `pgrep a.out`| tail -4 >> result_top.txt");
        printf("round %d finished\n", count);
        count++;
    }

    return 0;
}

现在我在每轮后记录驻留内存并将其重定向到文件result_top.txt。 这是文件result_top.txt

中的o / p
Round 0

/* Before Allocation RES */
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11053 root      20   0 11736  852  724 S  0.0  0.0   0:00.00 a.out

/* After allocation RES */
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11053 root      20   0 15688 4808  768 S  0.0  0.2   0:00.01 a.out

/* After Deletion RES*/
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11053 root      20   0 14904 4028  772 S  0.0  0.2   0:00.02 a.out


Round 1


  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11053 root      20   0 14908 4048  788 S  0.0  0.2   0:00.02 a.out


  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11053 root      20   0 15700 4828  788 S  0.0  0.2   0:00.05 a.out


  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11053 root      20   0 11872 1052  788 S  0.0  0.0   0:00.06 a.out

Round 2


  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11053 root      20   0 11872 1052  788 S  0.0  0.0   0:00.06 a.out


  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11053 root      20   0 15688 4828  788 S  0.0  0.2   0:00.08 a.out


  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11053 root      20   0 11872 1052  788 S  0.0  0.0   0:00.09 a.out


Round 3


  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11053 root      20   0 11872 1052  788 S  0.0  0.0   0:00.09 a.out


  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11053 root      20   0 15688 4828  788 S  0.0  0.2   0:00.11 a.out


  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
11053 root      20   0 11872 1052  788 S  0.0  0.0   0:00.13 a.out

现在在第0轮,当我释放驻留的内存是4028并且在分配内存之前的第二次迭代中它变为4048.

  

增加20个字节

在第一轮之后,每一轮的一切都很顺利。那么这个20字节增加的原因是什么?

类似的情况也发生在我的项目代码中。

2 个答案:

答案 0 :(得分:0)

我不清楚为什么会看到这种效果,但请注意,操作系统不负责实现新的/删除功能。操作系统提供的唯一帮助是更改分配给进程的内存总大小(通常通过Unix-ish系统上的brk()/ sbrk()请求)。

因此,您看到的明显泄漏与新/删除的具体实施有关。很可能这些不是垃圾收集&#34;未使用的内存,直到第二次删除调用满足的条件之后。在他们达到这个目标并要求减少分配给该进程的内存总大小之前,您无法观察到内存现在可以从像top这样的工具中解放出来。

在某种程度上,这是内存泄漏,因为空闲内存不会尽快返回到操作系统。但是,您可能相信新/删除实现应以合理的方式释放内存,避免过度浪费内存。

在C ++中,如果默认值不符合您的需要,您可以更改new / delete的实现...

答案 1 :(得分:0)

我自己接受了这段代码并执行了。 我认为在零回零之后你看到的20字节增加是因为尚未遇到的代码部分。因此它尚未映射到驻留内存。 现在,当遇到将要映射到驻留内存的新代码时。

所以你看到的20字节会增加。

要确定这一点,您可以删除上次最高记录后新遇到的代码,并检查常驻内存,20k将不会出现。