为什么Valgrind-Massif和TOPs内存消耗存在差异?

时间:2017-04-24 14:53:52

标签: c++ linux memory valgrind massif

我想测量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; }
    
  2. TOP命令显示当程序处于延迟功能时消耗了4200KB的虚拟内存。 Valgrind-Massif工具的消耗量为6340608B。哪一个是正确的?为什么会有差异?

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

      #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;}
      
    2. 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运行程序时,我也增加了堆栈大小,所以我不会得到堆栈溢出。我仍然得到相同的结果。

1 个答案:

答案 0 :(得分:1)

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