En garbage collector (GC) är en minneshanterare. Många programmeringsspråk har en inbyggd GC. Denna funktion tilldelar och avallokerar automatiskt minnet i ett program. Det frigör bundet, oanvänt minne som saktar ner din applikation.
Det fina med en GC är att den frigör minne för din räkning, utan att du behöver göra något. Du kanske därför anser att det är en så viktig funktion att du förväntar dig att alla programmeringsspråk har det. Tyvärr är detta inte fallet; även ett populärt språk som C kan sakna en GC.
Hur fungerar minnesallokering?
När du kör ett program på valfritt programmeringsspråk reserverar ditt operativsystem en datastack i minnet för det programmet. Detta program äger och ockuperar denna datastack tills den slutför exekvering. Om ditt program behöver mer minne än vad som är tillgängligt kan det dynamiskt allokera mer minne från operativsystemets minneshög.
Vid programmering representerar en variabel en minnesplats. Så när du deklarerar en ny variabel allokerar programmeringsspråket utrymme i minnet för denna variabel. Variabeln kommer nu att ha en minnesadress. Tills du tilldelar ett värde till denna variabel kommer den att förbli oinitierad, och den kan innehålla ett skräpvärde.
Om ett programmeringsspråk tillåter dig att deklarera en variabel utan att initiera den, så är det en dynamisk variabel. Det betyder att värdet du tilldelar variabeln kan ändras över tiden. Men minnesplatsen för variabeln kommer att förbli densamma tills du avallokerar den.
Hur fungerar minnesdeallokering?
Minnestilldelning är en liknande process för alla programmeringsspråk. Men motsvarande metod för minnesdeallokering tenderar att skilja sig åt. Det finns två typer av minnesavallokeringsmetoder; manuell och automatisk. En GC gör automatisk avallokering.
Minnesdeallokering utan sophämtare
De C programmeringsspråk använder inte en GC för minnesdeallokering. Därför måste C-programmerare manuellt allokera och avallokera minne. C tillåter dynamisk minnesallokering för när du inte vet, vid kompilering, hur mycket minne du kommer att använda vid körning.
Standardbiblioteket (stdlib.h) innehåller de funktioner som C använder för att hantera dynamisk minnesallokering. Dessa funktioner inkluderar:
- malloc(): allokerar en specifik minnesstorlek och returnerar en pekare till det minnet. Om det inte finns tillräckligt med minne i operativsystemets minnespool, returneras null.
- free(): avallokerar ett specifikt minnesblock och returnerar det till operativsystemets minnespool.
C Programexempel
#omfatta
#omfattainthuvud()
{
int *ptr; // deklarera pekare
int j; // deklarera räknare// allokera utrymme för 200 heltal
ptr = (int *) malloc(200 * storlek av(int));// infoga heltalsvärden i det tilldelade minnet
// och skriv ut varje värde till konsolen
för (j = 0; j < 200; j++)
{
ptr[j] = j;
printf("%d\t",ptr[j]);
}
// avallokera det tidigare tilldelade minnet
fri(ptr);
lämna tillbaka0;
}
Koden ovan allokerar minne för att lagra 200 heltalsvärden med hjälp av malloc() fungera. Den använder en pekare för att komma åt denna minnesplats och lagrar 200 heltalsvärden i den. Pekaren skriver också ut data som lagrats på minnesplatsen till konsolen. Slutligen avallokerar programmet det tidigare tilldelade minnet med hjälp av fri() fungera.
Minnesdeallokering med en sophämtare
Flera populära programmeringsspråk använder en GC för minneshantering. Detta gör livet för programmerare som använder dessa språk mycket enklare. C# och Java är två programmeringsspråk som använder en GC.
C# GC
I den C# programmeringsspråk, en GC hanterar allokeringen och deallokeringen av minnesadresser. Därför behöver en C#-programmerare inte oroa sig för att deallokera ett objekt efter att det har slutfört sitt syfte.
C# GC initierar en minnespool, kallad den hanterade högen, för varje ny process (eller program). Den kallar VirtualAlloc() funktion för att allokera minne och VirtualFree() funktion för att deallokera den. Det bästa är att allt detta sker i bakgrunden utan att du behöver anstränga dig, programmeraren.
C# GC har en optimeringsmotor som den använder för att bestämma när minne ska deallokeras. Optimeringsmotorn undersöker applikationsroten för att avgöra vilka objekt som inte längre används. Den gör detta genom att skapa en graf som sträcker sig från applikationens rot till anslutna objekt. Denna rot innehåller statiska fält, lokala variabler, etc. Alla objekt som inte är anslutna till programroten är skräp.
GC-optimeringsmotorn samlar inte bara minne på egen hand. Det måste först finnas en ny begäran om minnesallokering. Om systemet har en låg mängd tillgängligt minne, kommer GC-optimeringsmotorn att träda i kraft.
Java GC
I Java hanterar en GC även allokering och avallokering av minnesadresser. Men Java har för närvarande fyra olika typer av sopsamlare som stöds:
- Garbage-First (G1)
- Serie
- Parallell
- Z Garbage Collector (ZGC)
G1-sopsamlaren är Javas standard-GC sedan lanseringen av Java Development Kit (JDK) 9. Java organiserar data i objekt och lagrar dessa objekt i en hög med fast storlek. G1-sopsamlaren delar upp högen i lika stora högregioner. Den delade sedan dessa högregioner i två sektioner; unga och gamla generationer.
Varje gång du skapar ett nytt objekt sker utrymmesallokering för detta objekt i den unga generationen. Med hjälp av en åldringsprocess kopierar G1-sopsamlaren föremål i de unga regionerna till de gamla regionerna. Den kopierar också objekt som redan finns i den gamla regionen till en äldre region.
G1-sopsamlaren utför sedan det mesta av minnesfördelningen i den unga generationen, och vågar sig då och då till den gamla generationens sektion.
Vilka är fördelarna med att ha en sophämtare?
Fördelen med att ha en sophämtare är att den hindrar dig från att tänka på minneshantering medan du skriver din kod. Detta ger dig tid att fokusera på de andra viktiga aspekterna av din ansökan. Flera andra fördelar är dock värda att lyfta fram.
Att återta oanvända objekt och frigöra minne ger renare programexekvering. Om ditt program frigör minne så snart som möjligt kommer det att ha ett mindre minnesutrymme och kan köras mer effektivt.
Sophämtning minskar fel relaterade till minneshantering som läckor och pekarfel. Detta beror på att processen inte längre är beroende av programmeraren och deras förmåga att skriva korrekt kod.