c + + - Hvorfor fortsætter en hukommelselæk ikke, efter at du har spist?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg skabte et forsætligt hukommelseslækage for at vise et punkt til folk, der snart vil lære vejledninger.


int main()
{
    while (1)
    {
        int *a = new int [2];
        //delete [] a;
    }
}


Hvis dette kører uden den kommenterede kode, forbliver hukommelsen lav og stiger ikke som forventet. Men hvis dette kører som det er, så på en maskine med 2 GB RAM, stiger hukommelsesforbruget hurtigt til ca. 1,5 GB, eller hvad der ikke er i brug af systemet. Når det først er kommet til dette punkt, falder CPU-brugen (som tidligere var max) kraftigt og hukommelsesbrugen også ned til ca. 100 MB.


Hvad der netop forårsagede denne intervenerende handling (hvis der er noget mere specifikt end 'Windows', det vil være fantastisk), og hvorfor tager programmet ikke CPU'en i gang, men det ophører heller ikke? Det lader til, at det sidder fast mellem loopens ende og slutningen af ​​hovedet.


Windows XP, GCC, MinGW.

Bedste reference


Hvad der sandsynligvis sker er, at din kode allokerer alt tilgængeligt fysisk RAM. Når det når den grænse, begynder systemet at allokere plads på swapfilen for det. Det betyder at det næsten hele tiden venter på disken, så dets CPU-brugen falder til (næsten) nul.


Systemet kan let holde øje med det faktum, at det aldrig rent faktisk skriver til den hukommelse, det tildeler, så når det skal gemmes på swapfilen, vil det bare lave et lille rekord, der grundlæggende siger ' proces X har N bytes uninitialized storage 'i stedet for faktisk at kopiere alle data til harddisken (men jeg er ikke sikker på det, og det kan meget vel afhænge af det nøjagtige system du bruger).

Andre referencer 1


For at omskrive Inigo Montoya, 'tror jeg ikke, det betyder hvad du mener det betyder.' Windows-task manager viser ikke de hukommelsesbrugesdata, du leder efter.


Kolonnen 'Mem Usge' viser noget, der er relateret til arbejdssætets størrelse (eller den residente sætstørrelse) af processen. Det vil sige, at 'Mem Usage' viser et nummer relateret til mængden af ​​fysisk hukommelse, der i øjeblikket er tildelt til din proccess.


Kolonnen 'VM Size' viser et tal, der ikke er relateret til det virtuelle hukommelsessystem (det er faktisk størrelsen af ​​de private høje, der er tildelt af processen.


Prøv at bruge et andet værktøj til visuel virtuel hukommelsesbrug. Jeg foreslår Process Explorer. [4]

Andre referencer 2


Jeg antager, at når programmet slukker den tilgængelige fysiske hukommelse, begynder den at bruge on-disk (virtuel) hukommelse, og det bliver så langsomt, det virker som om det er inaktivt. Prøv at tilføje en vis hastighedsvisualisering:


int counter = 0;
while (1)
{
    int *a = new int [2];
    ++counter;
    if (counter \% 1000000 == 0)
        std::cout << counter << '
'
}

Andre referencer 3


Standardhukommelseskolonnen i task manager for XP er størrelsen af ​​arbejdssættet i processen (mængden af ​​fysisk hukommelse, der er allokeret til den proces), ikke den faktiske hukommelsesforbrug.


http://msdn.microsoft.com/en-us/library/windows/desktop/ms684891\%28v=vs.85\%29.aspx[5]


http://blogs.msdn.com/b/salvapatuel/archive/2007/10/13/memory-working-set-explored.aspx[6]

Andre referencer 4


Kolonnen 'Mem Usage' i task manager er sandsynligvis det 'arbejdssæt' som forklaret af et par svar i dette spørgsmål, men for at være ærlig bliver jeg stadig forvirret over, hvordan task manager refererer til hukommelse, da den skifter fra version til version. Denne værdi går op/ned, da du naturligvis ikke bruger meget hukommelse til enhver tid. Hvis du kigger på 'VM Size', skal du se det hele tiden stige, indtil der sker noget dårligt.


Du kan også give Process Explorer et forsøg, som jeg let kan forstå i, hvordan det viser ting. [8]

Andre referencer 5


Flere ting: For det første, hvis du kun tildeler 2 int s ad gangen, det
Det kan tage timer, før du bemærker, at den samlede hukommelsesforbrug går
op på grund af det. Og for det andet gør det på mange systemer ikke tildeling
begå, indtil du rent faktisk har adgang til hukommelsen adresserummet kan være
reserveret, men du har virkelig ikke hukommelsen (og programmet vil
crash hvis du forsøger at få adgang til hukommelsen, og der er ikke noget tilgængeligt).


Hvis du vil simulere en lækage, anbefaler jeg at allokere mindst en side
ad gangen, hvis ikke væsentligt mere, og skrive mindst en byte ind
hver tildelt side.