/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
måle hukommelse forbrug
Fra : Hans Hvelplund Odbor~


Dato : 20-12-03 22:01

I linux:

Hvordan måler jeg det maksimale hukommelseforbrug af en applikation?
/proc/<proces-id>/status kan tilsyneladende vise mig hvad der bliver
brugt ligge nu, men jeg vil gerne have det maksimale hukommelseforbrug.


 
 
Anders Wegge Jakobse~ (20-12-2003)
Kommentar
Fra : Anders Wegge Jakobse~


Dato : 20-12-03 23:16

"Hans" == Hans Hvelplund Odborg <odborg@REMOVE_THIScs.auc.dk> writes:

> I linux:
> Hvordan måler jeg det maksimale hukommelseforbrug af en applikation?
> /proc/<proces-id>/status kan tilsyneladende vise mig hvad der bliver
> brugt ligge nu, men jeg vil gerne have det maksimale hukommelseforbrug.

Du kan bruge enten memprof eller time. Memprof giver dig en pæn
farvelade med øjebliksværdier og peaks, og kan tilsyneladende også
finde memory leaks. GNU time kan ifølge mansiden også måle på
hukommelsesforbrug, men jeg ved ikke hvor godt det virker - jeg kan
ihvertfald ikke lige få den til at kramme ud med mere end køretiderne.

--
/Wegge <http://outside.bakkelygaard.dk/~wegge/>
echo mail: !#^."<>"|tr "<> mail:" dk@wegge

Byrial Jensen (21-12-2003)
Kommentar
Fra : Byrial Jensen


Dato : 21-12-03 00:59

Anders Wegge Jakobsen wrote:
> "Hans" == Hans Hvelplund Odborg <odborg@REMOVE_THIScs.auc.dk> writes:
>
>>linux:
>
> GNU time kan ifølge mansiden også måle på
> hukommelsesforbrug, men jeg ved ikke hvor godt det virker - jeg kan
> ihvertfald ikke lige få den til at kramme ud med mere end køretiderne.

Hmm, det kan jeg tilsyneladende heller ikke idet den kun giver 0 som
resultat for hukommelsesmålingerne.

time(1) er i princippet implementeret sådan her:

#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <stdio.h>

int main (int argc, char *argv[])
{
if (fork ())
{
struct rusage rusage;
wait3 (0, 0, &rusage);
printf ("Max. RSS: %lu\n", rusage.ru_maxrss);
}
else
{
execvp (argv[1], argv + 1);
}
}

Programmet virker bortset signalhåndtering og fejlkontrol, men giver
også altid 0 som måleresultat. Det tyder på at wait-kaldet ikke giver
hukommelsesmål som dokumenteret. Det er testet på Linux 2.4.21.


Hans Hvelplund Odbor~ (21-12-2003)
Kommentar
Fra : Hans Hvelplund Odbor~


Dato : 21-12-03 15:02

> Programmet virker bortset signalhåndtering og fejlkontrol, men giver
> også altid 0 som måleresultat. Det tyder på at wait-kaldet ikke giver
> hukommelsesmål som dokumenteret. Det er testet på Linux 2.4.21.

iflg. man getrusage under NOTES:
Right now (Linux 2.4) only the fields ru_utime,
ru_stime, ru_minflt, ru_majflt, and ru_nswap are maintained.


Byrial Jensen (22-12-2003)
Kommentar
Fra : Byrial Jensen


Dato : 22-12-03 18:09

Hans Hvelplund Odborg wrote:
>> Programmet virker bortset signalhåndtering og fejlkontrol, men giver
>> også altid 0 som måleresultat. Det tyder på at wait-kaldet ikke giver
>> hukommelsesmål som dokumenteret. Det er testet på Linux 2.4.21.
>
> iflg. man getrusage under NOTES:
> Right now (Linux 2.4) only the fields ru_utime,
> ru_stime, ru_minflt, ru_majflt, and ru_nswap are maintained.

Tak for det. Jeg var ikke opmærksom på den note.


Hans Hvelplund Odbor~ (21-12-2003)
Kommentar
Fra : Hans Hvelplund Odbor~


Dato : 21-12-03 15:43

Anders Wegge Jakobsen wrote:
> Du kan bruge enten memprof eller time. Memprof giver dig en pæn
> farvelade med øjebliksværdier og peaks

Desværre er memprof ikke helt nøjagtig.
Så vidt jeg har kan se er det ikke garanteret at memprof finder peaks.
Kørsel af mit program giver ikke altid de samme peaks (og det er ikke
pga leaks, for dem er der ingen af (så vidt jeg kan se, og iflg memprof).

Der udover er angivelsen af peaks ret unøjagtig når den endelig har et
bud, for den viser kun tal for det der er allokeret på et givet
tidspunkt, ikke hvor meget der har været allokeret (det må man pænt
aflæse så godt man nu kan)


Anders Wegge Jakobse~ (21-12-2003)
Kommentar
Fra : Anders Wegge Jakobse~


Dato : 21-12-03 19:19

"Hans" == Hans Hvelplund Odborg <odborg@REMOVE_THIScs.auc.dk> writes:

> Anders Wegge Jakobsen wrote:
>> Du kan bruge enten memprof eller time. Memprof giver dig en pæn
>> farvelade med øjebliksværdier og peaks

> Desværre er memprof ikke helt nøjagtig.
> Så vidt jeg har kan se er det ikke garanteret at memprof finder peaks.
> Kørsel af mit program giver ikke altid de samme peaks (og det er ikke
> pga leaks, for dem er der ingen af (så vidt jeg kan se, og iflg
> memprof).

Nej, og selv hvis du havde leaks, ville du formentlig stadig komme
frem til den samme værdi.

> Der udover er angivelsen af peaks ret unøjagtig når den endelig har et
> bud, for den viser kun tal for det der er allokeret på et givet
> tidspunkt, ikke hvor meget der har været allokeret (det må man pænt
> aflæse så godt man nu kan)

Hvis ikke memprof er godt nok, og time tilsyneladende ikke fortæller
alverden, skal du nok ud i at implementere en wrapper uden om malloc()
og venner, i stil med efence, og så opretholde din peaktæller
derfra.


--
/Wegge <http://outside.bakkelygaard.dk/~wegge/>
echo mail: !#^."<>"|tr "<> mail:" dk@wegge

Byrial Jensen (22-12-2003)
Kommentar
Fra : Byrial Jensen


Dato : 22-12-03 18:27

Anders Wegge Jakobsen wrote:
> Hvis ikke memprof er godt nok, og time tilsyneladende ikke fortæller
> alverden, skal du nok ud i at implementere en wrapper uden om malloc()
> og venner, i stil med efence, og så opretholde din peaktæller
> derfra.

Der er to problemer med den løsning:
1) Man skulle vedligeholde en tabel med alle allokeringer så man ved
hvor meget hukommelse der frigives af free() og lignende. Det vil måske
påvirke det målte programs performance i negativ retning.
2) Man får ikke at vide hvor meget hukommelse der "går tabt" på grund af
overhead, fragmentering og lignende.

En anden mulighed er at bruge strace til at registere alle kernekald som
allokerer hukommelse (mmap og enkelte andre). Derudfra kan man så
efterfølgende beregne maksimumsværdier. Jeg ville nok gå den vej hvis
jeg skulle skrive et "memmax"-program.


Soeren Sandmann (22-12-2003)
Kommentar
Fra : Soeren Sandmann


Dato : 22-12-03 21:08

Byrial Jensen <bjensen@nospam.dk> writes:

> En anden mulighed er at bruge strace til at registere alle kernekald
> som allokerer hukommelse (mmap og enkelte andre). Derudfra kan man så
> efterfølgende beregne maksimumsværdier. Jeg ville nok gå den vej hvis
> jeg skulle skrive et "memmax"-program.

I princippet er der vel ikke noget i vejen for at en applikation
allokerer en masse hukommelse uden at bruge den. Dette program:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

#define N_BYTES 500000000

int
main ()
{
int i;

char *m = malloc (N_BYTES);

if (!m)
{
printf ("malloc() returnerede NULL\n");
return -1;
}

for (i = 0; i < N_BYTES; ++i)
{
if (0)
m[i] = 'x';
else
sleep (5);
}
}

får strace til at rapportere:

[...]
mmap2(NULL, 500002816, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x42133000

Der reserveres altså en forfærdelig masse sider, men fordi der aldrig
bliver skrevet noget på dem, bliver de allesammen ignoreret af kernens
VM-system. Så jeg synes ikke man kan sige at programmet bruger 500 MB
hukommelse.

På min computer, som har 256 MB RAM, har det ikke nogen synlig effekt
at køre programmet, men /proc/<pid>/status fortæller:

VmData: 488300 kB

Hvis man udelukkende er interesseret i det maksimale antal bytes
allokeret med malloc(), er tallet under VmData (størrelsen af
datasegmentet) i /proc/<pid>/status sikkkert ikke helt i
skoven. Tallet er bare ikke nødvendigvis noget rimeligt bud på hvor
meget hukommelse et program bruger.

En anden mulighed er at se på det maksimale antal sider der er blevet
skrevet til på samme tid, men det er heller ikke helt realistisk, for

(a) der kan være masser af sider som er indlæst i den fysiske
hukommelsen, men som aldrig er blevet skrevet til
(programmets kode fx), og

(b) der kan sagtens være sider som der engang er blevet
skrevet til, men som ikke bruges længere og som ikke er
indlæst i hukommelsen.

En tredje mulighed er udelukkende at tælle antallet af sider som er
indlæst i hukommelsen. Dette tal rapporteres af top i søjlen RSS og
står i /proc/<pid>/status under VmRSS. Dette tal viser hvor meget
fysisk hukommelse programmet bruger, men

(a) Størrelsen af RSS afhænger af hvor meget hukommelse andre
programmer bruger.

(b) Hvis programmet har brug for mere hukommelse end der er
til stede fysisk, vil RSS være lig med mængden af fysisk
hukommelse, og operativsystemet vil udskifte sider hele
tiden.

(c) En del af RSS kan være delt med andre programmer.

For programmet ovenfor er RSS således 260 kB. Hvis jeg ændrer "if (0)"
til "if (1)", så vokser RSS hurtigt til 200 MB hvorefter top holder op
med at svare.

Så det er svært at give et klart svar på hvor meget hukommelse et
givet program bruger.

Byrial Jensen (20-12-2003)
Kommentar
Fra : Byrial Jensen


Dato : 20-12-03 23:25

Hans Hvelplund Odborg wrote:
> I linux:
>
> Hvordan måler jeg det maksimale hukommelseforbrug af en applikation?
> /proc/<proces-id>/status kan tilsyneladende vise mig hvad der bliver
> brugt ligge nu, men jeg vil gerne have det maksimale hukommelseforbrug.

Programmet time kan gøre det. Se "man time" eller "info time".


Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408919
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste