我正在处理常驻内存增加问题。 为了模拟我编写了一个实际模拟我的问题的代码片段。
#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 / pRound 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字节增加的原因是什么?
类似的情况也发生在我的项目代码中。
答案 0 :(得分:0)
我不清楚为什么会看到这种效果,但请注意,操作系统不负责实现新的/删除功能。操作系统提供的唯一帮助是更改分配给进程的内存总大小(通常通过Unix-ish系统上的brk()/ sbrk()请求)。
因此,您看到的明显泄漏与新/删除的具体实施有关。很可能这些不是垃圾收集&#34;未使用的内存,直到第二次删除调用满足的条件之后。在他们达到这个目标并要求减少分配给该进程的内存总大小之前,您无法观察到内存现在可以从像top这样的工具中解放出来。
在某种程度上,这是内存泄漏,因为空闲内存不会尽快返回到操作系统。但是,您可能相信新/删除实现应以合理的方式释放内存,避免过度浪费内存。
在C ++中,如果默认值不符合您的需要,您可以更改new / delete的实现...
答案 1 :(得分:0)
我自己接受了这段代码并执行了。 我认为在零回零之后你看到的20字节增加是因为尚未遇到的代码部分。因此它尚未映射到驻留内存。 现在,当遇到将要映射到驻留内存的新代码时。
所以你看到的20字节会增加。
要确定这一点,您可以删除上次最高记录后新遇到的代码,并检查常驻内存,20k将不会出现。