我在C ++程序代码中添加了重启选项。每次重新启动时,我都会看到Resident内存增加,而valgrind没有显示任何泄漏。驻地记忆增加的原因是什么?
答案 0 :(得分:9)
有几个可能的原因:
vector<int> v; for(;;) v.push_back(1);
这样的东西会在几秒钟内耗尽内存,但根据valgrind的说法不会泄漏。 您可能希望使用valgrind,valgrind --tool=massif prog
的massif工具来识别#1等数据,其中数据随着时间的推移而逐渐增加。
编辑: 从链接中的页面:
Massif是一个堆分析器。它测量你的堆内存量 程序使用。这包括有用空间和额外字节 分配用于簿记和对齐目的。它也可以测量 程序堆栈的大小,尽管它没有这样做 默认值。
mem_heap_extra_B
是分配为“填充”和“开销”的字节数。它通常只占总分配大小的一小部分,但如果您有许多非常小的分配,它可以控制堆使用。
mem_stacks_B
是应用程序使用的堆栈字节数(默认情况下,这不会被测量,因为它会大大减慢代码速度)。
以此程序为例:
#include <vector>
int main(int argc, char **argv)
{
(void)argv; // Not used.
const int size = 10000;
std::vector<int*> v(size);
switch (argc)
{
case 1:
for(int i = 0; i < size; i++)
{
v[i] = new int;
};
for(int i = 0; i < size; i++)
{
delete v[i];
};
break;
case 2:
{
int *t = new int [size];
for(int i = 0; i < size; i++)
{
v[i] = t+i;
};
delete [] t;
break;
}
}
return 0;
}
以下是valgrind --tool=massif ./a.out
(代码的case 1:
变体)的输出(在高峰使用时):
time=2872338
mem_heap_B=120000
mem_heap_extra_B=200008
mem_stacks_B=0
heap_tree=peak
如果我们使用valgrind --tool=massif ./a.out 1
运行(代码为case 2:
),则在使用高峰时,输出为:
time=2523909
mem_heap_B=120000
mem_heap_extra_B=16
mem_stacks_B=0
heap_tree=peak
注意mem_heap_extra_B
的不同之处 - 在第一种情况下,它大于实际的堆使用量(因为每4字节分配实际上占用了更多),其中在第二种情况下,额外的字节是只有16,但堆的实际“使用”大小是相同的,120000(这是有道理的,我们有8个字节的10000个指针,每个4个字节的10000个整数)。
不幸的是,这个程序在堆栈使用方面相当无趣,但如果你使用--stacks=yes
,它将显示所用堆栈的字节数,例如:
time=2222719
mem_heap_B=120000
mem_heap_extra_B=16
mem_stacks_B=528
如果我正在研究Pascal编译器中的mem_stacks_B
,那么它会变得更有趣:
10:mem_stacks_B=0
18:mem_stacks_B=1576
26:mem_stacks_B=1368
34:mem_stacks_B=1368
42:mem_stacks_B=1576
50:mem_stacks_B=120
58:mem_stacks_B=2592
66:mem_stacks_B=4656
288:mem_stacks_B=2464
296:mem_stacks_B=43104
431:mem_stacks_B=2424
439:mem_stacks_B=10960
447:mem_stacks_B=8096
622:mem_stacks_B=8352
887:mem_stacks_B=3816
895:mem_stacks_B=3360
903:mem_stacks_B=3664
911:mem_stacks_B=3216
还有很多,但足以表明“堆栈使用量变化很大”。
正如您所看到的,它有很大差异。不,我没有试图弄清楚当它使用43KB的堆栈时它正在做什么 - 无论如何它并不是真的太过分了。