2

我想测量linux ubuntu中程序的内存消耗。我比较了两个工具:Valgrind Massif 和 TOP。出于某种原因,即使我使用“--pages-as-heap=yes”来显示所有内存,我也得到了不同的结果。

  1. 我编译了以下代码:

    void delay(double secs)
    {
        int i,j;
        for(j=0;j<5000*secs;j++)
            for(i=0;i<99999;i++);
    }
    int main() {
        delay(30);
    return 0; }
    

TOP 命令显示程序在延迟函数中时消耗了 4200KB 的虚拟内存。Valgrind-Massif 工具的消耗量为 6340608B。哪一个是正确的?为什么有区别?

  1. 虽然 Massif 网站告诉启用“--pages-as-heap=yes”选项,堆栈也被测量,但我没有成功。例如,对于以下程序:

    #include <stdlib.h>
    void delay(double secs)
    {
        int i,j;
        for(j=0;j<5000*secs;j++)
            for(i=0;i<99999;i++);
    }
    void func(int n)
    {
       char x[2000000];
       int i;
       if(n==0)
       return;
       for(i=0;i<2000000;i++)
           x[i]=(char)n;
       delay(15);   // Delay number 2,3,4,5
       func(n-1);
       return;
    }
    int main() {
       delay(30);   // Delay number 1
       func(4);
       delay(30);   // Delay number 6
       return 0;}
    

TOP 报告的内存消耗为:4200 KB,然后是 6032KB,然后是 7984 KB,然后是 9936 KB,然后是 11892 KB,然后是 13844 KB。但是Massif在程序开始的时候只报了6336512 B(其实内存有一些波动,但是很快就停了,而且不是很大)。似乎出于某种原因,Massif 没有在此设置下测量堆栈。为什么会这样?

编辑:

我尝试在发布模式下编译,但遇到了同样的问题。我编译了以下代码:

#include<stdio.h>
#include <stdlib.h>
unsigned long delay(double secs)
{   long i,j,k,counter=0;
    for(k=0;k<160000;k++)
    for(j=0;j<5000*secs;j++)
        for(i=0;i<99999;i++)
            counter++;
    return counter;
}
int main() 
{
    unsigned long i;
    i=delay(10);
    printf("%lu\n",i);
    return 0;
}

TOP 还是 4200KB,Massif 大约 6MB。我使用以下命令编译了代码:

g++ -O2 -Wall myprog.c -o myprog

此外,当我运行程序时,我使用以下命令增加了堆栈大小: ulimit -s 2000000000 并且在使用 Massif 运行程序时我还增加了堆栈大小,因此我不会遇到堆栈溢出。我仍然得到相同的结果。

4

1 回答 1

1

看起来您正在尝试分析调试版本(这完全没有意义)。因为在发布版本中,这两个程序都将只有一个虚拟的 main proc 作为编译器,因为它们没有副作用,所以会丢弃所有计算。第二个程序也会导致堆栈溢出,因为您试图在堆栈上分配巨大的数组。

于 2017-04-24T19:48:14.127 回答