Indledning

Hukommelsesstyring er processen med effektiv allokering, deallokering og koordinering af hukommelse, så alle de forskellige processer kører problemfrit og kan få optimal adgang til forskellige systemressourcer. Hukommelsesstyring omfatter også rensning af hukommelse for objekter, der ikke længere er tilgængelige.

I Python er hukommelseshåndteringen ansvarlig for disse typer opgaver ved periodisk at køre for at rydde op, allokere og administrere hukommelsen. I modsætning til C, Java og andre programmeringssprog administrerer Python objekter ved hjælp af referencetælling. Det betyder, at memory manager holder styr på antallet af referencer til hvert objekt i programmet. Når et objekts referencetælling falder til nul, hvilket betyder, at objektet ikke længere bruges, frigør garbage collector (en del af memory manager) automatisk hukommelsen fra det pågældende objekt.

Brugeren behøver ikke at bekymre sig om hukommelsesstyring, da processen med allokering og de-allokering af hukommelse er helt automatisk. Den genvundne hukommelse kan bruges af andre objekter.

Python Garbage Collection

Som forklaret tidligere sletter Python objekter, der ikke længere refereres i programmet, for at frigøre hukommelsesplads. Denne proces, hvor Python frigør blokke af hukommelse, der ikke længere bruges, kaldes Garbage Collection. Pythons Garbage Collector (GC) kører under programudførelsen og udløses, hvis referencetallet reduceres til nul. Referencetallet stiger, hvis et objekt tildeles et nyt navn eller placeres i en container, f.eks. en tuple eller en ordbog. På samme måde falder referencetallet, når referencen til et objekt tildeles igen, når objektets reference går ud af rækkevidde, eller når et objekt slettes.

Hukommelsen er en bunke, der indeholder objekter og andre datastrukturer, der anvendes i programmet. Allokering og de-allokering af denne heap-plads styres af Pythons hukommelsesmanager ved hjælp af API-funktioner.

Python-objekter i hukommelsen

Hver variabel i Python fungerer som et objekt. Objekter kan enten være simple (indeholdende tal, strenge osv.) eller containere (ordbøger, lister eller brugerdefinerede klasser). Desuden er Python et dynamisk typet sprog, hvilket betyder, at vi ikke behøver at deklarere variablerne eller deres typer, før vi bruger dem i et program.

For eksempel:

Hvis du ser på de første 2 linjer i ovenstående program, er objekt x kendt. Når vi sletter objektet x og forsøger at bruge det, får vi en fejl, der siger, at variablen x ikke er defineret.

Du kan se, at garbage collection i Python er fuldt automatiseret, og programmøren behøver ikke at bekymre sig om det i modsætning til sprog som C.

Modificering af garbage collector

Python garbage collector har tre generationer, hvori objekter klassificeres. Et nyt objekt ved startpunktet af dets livscyklus er første generation af garbage collector’en. Efterhånden som objektet overlever garbage collection, flyttes det op til de næste generationer. Hver af de tre generationer af skraldesamleren har en tærskelværdi. Nærmere bestemt, når tærsklen for antallet af allokeringer minus antallet af de0allokeringer er overskredet, vil den pågældende generation køre garbage collection.

Forrige generationer bliver også garbage collectioneret oftere end de højere generationer. Dette skyldes, at nyere objekter er mere tilbøjelige til at blive kasseret end gamle objekter.

Det gc modul indeholder funktioner til at ændre tærskelværdien, udløse en garbage collection-proces manuelt, deaktivere garbage collection-processen osv. Vi kan kontrollere tærskelværdierne for de forskellige generationer af garbage collector ved hjælp af get_threshold()-metoden:

import gcprint(gc.get_threshold())

Sample Output:

(700, 10, 10)

Som du kan se, har vi her en tærskelværdi på 700 for den første generation og 10 for hver af de to andre generationer.

Vi kan ændre tærskelværdien for udløsning af garbage collection-processen ved hjælp af set_threshold()-metoden i gc-modulet:

gc.set_threshold(900, 15, 15)

I ovenstående eksempel har vi øget tærskelværdien for alle 3 generationer. En forøgelse af tærskelværdien vil reducere frekvensen af kørsel af garbage collector. Normalt behøver vi ikke at tænke så meget på Pythons garbage collection som udvikler, men dette kan være nyttigt, når du optimerer Pythons runtime til dit målsystem. En af de vigtigste fordele er, at Pythons garbage collection-mekanisme håndterer en masse detaljer på lavt niveau for udvikleren automatisk.

Hvorfor udføre manuel garbage collection?

Vi ved, at Python-fortolkeren holder styr på referencer til objekter, der bruges i et program. I tidligere versioner af Python (indtil version 1.6) anvendte Python-fortolkeren kun referencetællingsmekanismen til at håndtere hukommelse. Når referencetællingen falder til nul, frigør Python-fortolkeren automatisk hukommelsen. Denne klassiske referencetællingsmekanisme er meget effektiv, bortset fra at den ikke fungerer, når programmet har referencecyklusser. En referencecyklus opstår, hvis et eller flere objekter refererer til hinanden, og derfor når referencetallet aldrig ned på nul.

Lad os se på et eksempel.

>>> def create_cycle():... list = ... list.append(list)... return list... >>> create_cycle()]

Overstående kode skaber en referencecyklus, hvor objektet list refererer til sig selv. Derfor vil hukommelsen til objektet list ikke automatisk blive frigjort, når funktionen vender tilbage. Problemet med referencecyklus kan ikke løses ved hjælp af referencetælling. Dette referencecyklusproblem kan dog løses ved at ændre garbage collectorens adfærd i din Python-applikation.

For at gøre dette kan vi bruge gc.collect()-funktionen i gc-modulet.

import gcn = gc.collect()print("Number of unreachable objects collected by GC:", n)

Den gc.collect() returnerer antallet af objekter, den har indsamlet og de-allokeret.

Der er to måder at udføre manuel garbage collection på: tidsbaseret eller begivenhedsbaseret garbage collection.

Tidsbaseret garbage collection er ret simpelt: gc.collect()-funktionen kaldes efter et fast tidsinterval.

Hændelsesbaseret garbage collection kalder gc.collect()-funktionen efter en begivenhed (dvs. når programmet afsluttes, eller programmet forbliver inaktivt i et bestemt tidsrum).

Lad os forstå det manuelle garbage collection-arbejde ved at oprette et par referencecyklusser.

Opdatet ser ud som nedenfor:

Creating garbage...Collecting...Number of unreachable objects collected by GC: 8Uncollectable garbage: 

Scriptet ovenfor opretter et listeobjekt, der refereres af en variabel, der kreativt kaldes list. Det første element i listeobjektet henviser til sig selv. Referencetallet for listeobjektet er altid større end nul, selv om det er slettet eller uden for rækkevidde i programmet. Derfor bliver list-objektet ikke indsamlet i skraldespanden på grund af den cirkulære reference. Garbage collector-mekanismen i Python vil automatisk kontrollere og indsamle cirkulære referencer med jævne mellemrum.

I ovenstående kode har vi, da referencetallet er mindst 1 og aldrig kan nå op på 0, tvangsindsamlet objekternes garbage collection ved at kalde gc.collect(). Husk dog, at du ikke skal tvinge garbage collection ofte. Årsagen er, at GC selv efter frigørelse af hukommelsen tager tid til at vurdere, om objektet er berettiget til at blive skraldet, hvilket optager processortid og ressourcer. Husk også, at du først skal administrere garbage collector manuelt, når din app er startet helt.

Konklusion

I denne artikel har vi diskuteret, hvordan hukommelsesstyring i Python håndteres automatisk ved hjælp af referencetælling og garbage collection-strategier. Uden garbage collection er det umuligt at implementere en vellykket hukommelsesstyringsmekanisme i Python. Programmører behøver heller ikke at bekymre sig om sletning af allokeret hukommelse, da Pythons hukommelseshåndtering tager sig af det. Dette fører til færre hukommelseslækager og bedre ydeevne.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.