Я хочу измерить потребление памяти программой в Linux Ubuntu. Я сравнил два инструмента: массив Valgrind и TOP. По некоторым причинам, я получил разные результаты, даже когда использовал «—pages-as-heap = yes», чтобы показать всю память.
Я скомпилировал следующий код:
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 показала потребление 4200 КБ виртуальной памяти, когда программа находилась в функции задержки. Инструмент Valgrind-Massif дал расход 6340608B. Какой из них правильный? И почему есть разница?
Хотя веб-сайт 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 КБ, затем 6032 КБ, затем 7984 КБ, затем 9936 КБ, затем 11892 КБ, а затем 13844 КБ. Тем не менее, 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;
}
и все еще получил 4200 КБ с ТОПом и около 6 МБ с массивом.
Я скомпилировал код с помощью следующей команды:
g++ -O2 -Wall myprog.c -o myprog
Также, когда я запустил программу, я увеличил размер стека с помощью:
ulimit -s 2000000000
и я также увеличил размер стека при запуске программы с Massif, так что я не получу переполнение стека. И я все еще получаю те же результаты.
Похоже, вы пытаетесь профилировать отладочные сборки (что совершенно бессмысленно). Потому что в сборках релизов обе эти программы будут иметь только фиктивный основной процесс в качестве компилятора, который отбрасывает все вычисления, поскольку они не имеют побочных эффектов. Также вторая программа вызывает переполнение стека, потому что вы пытаетесь выделить огромные массивы в стеке.
Других решений пока нет …