Programmering

Mine to cent på GC.Collect-metoden i C #

GC.Collect () -metoden har længe været populær blandt .Net-udviklere. Imidlertid ved næppe få af os, hvordan det rent faktisk fungerer, eller hvis det overhovedet er nødvendigt at ringe til det.

CLR (Common Language Runtime) vedtager affaldsindsamling som en mekanisme til at rydde op i de ressourcer, der forbruges af din applikation. Bemærk, at når du opretter objekter i .Net, gemmes de i den administrerede bunke, og når du er færdig med at bruge dem, behøver du ikke bekymre dig om at rense dem - runtime ville gøre det for dig.

CLR organiserer den administrerede dyng i generationer. De tre generationer, som den administrerede bunke er organiseret i, er: Generation 0, Generation 1 og Generation 2. GC er dygtig til at genvinde hukommelsen, der er optaget af administrerede objekter. Du skal dog følge visse retningslinjer for at lette hurtigere affaldsindsamling for at forbedre din applikations ydeevne.

Skal jeg bruge metoden GC.Collect ()?

For det første skal du overhovedet ringe til GC.Collect i din applikations kode? Svaret er i de fleste tilfælde nej. Lad mig nu fortælle dig, hvad denne metode gør, og hvorfor du i de fleste tilfælde bør afstå fra at kalde denne metode.

Når du foretager et opkald til GC.Collect () -metoden, udfører runtime en stakgang for at bestemme de objekter, der kan nås, og dem der ikke er. Det fryser også hovedtråden (og også eventuelle underordnede tråde, den oprettede) i applikationen. Med andre ord, når GC.Collect () -metoden kaldes, udfører runtime en blokerende affaldssamling af alle generationer.

Jeg foretrækker altid ikke at bruge GC.Collect (), medmindre der er en specifik grund til at bruge det. En GC består typisk af Mark- og Sweep-faser efterfulgt af en komprimeringsfase. Tiden brugt af runtime til at udføre en GC kan blive en flaskehals, så brug den kun meget sjældent, og hvis du virkelig har brug for det. Rico Mariani siger: "Overvej at ringe til GC.Collect (), hvis der er sket en begivenhed, der lige er gentagne gange, og denne begivenhed sandsynligvis har fået mange gamle genstande til at dø."

Brug GC.Collect () -metoden

Sådan kan du påberåbe sig GC.Collect () -metoden i din kode.

GC.Collect ();

Bemærk, at du også kan samle objekter, der vedrører en bestemt generation.

GC.Collect () - bruges til at samle genstande til stede i generationerne 0, 1, 2

GC.Collect (0) - bruges til at samle genstande til stede i generation 0

GC.Collect (1) - bruges til at samle genstande til stede i generationer 0 og

Du kan også bestemme, hvor meget hukommelse der er frigjort ved at ringe til GC.Collect () -metoden. For at gøre dette kan du drage fordel af System.GC.GetTotalMemory () -metoden som vist i kodestykket nedenfor.

// Skriv kode for at oprette nogle store objekter her

Console.WriteLine ("Samlet tilgængelig hukommelse før samling: {0: N0}", System.GC.GetTotalMemory (falsk));

System.GC.Collect ();

Console.WriteLine ("Samlet tilgængelig hukommelsessamling: {0: N0}", System.GC.GetTotalMemory (true));

GC.GetGeneration () -metoden kan bruges til at kende den generation, som et objekt tilhører. Se kodelisten nedenfor.

statisk ugyldigt Main (streng [] args)

       {

Liste obj = ny liste () {"Joydip", "Steve"};

Console.WriteLine (System.GC.GetGeneration (obj));

System.GC.Collect ();

Console.WriteLine (System.GC.GetGeneration (obj));

System.GC.Collect ();

Console.WriteLine (System.GC.GetGeneration (obj));

Console.Read ();

       }

Når du udfører ovenstående program, her er hvad der udskrives i konsolvinduet.

0

1

2

Som du kan se, fremmer hvert opkald til GC.Collect () -metoden objektet "obj" til den næste højere generation. Dette skyldes, at objektet "obj" overlever affaldssamlingen i hvert af de to tilfælde, dvs. det genvindes ikke i nogen af ​​de to opkald foretaget til GC.Collect () -metoden.

Du kan tvinge affaldsindsamling til enten de tre generationer eller til en bestemt generation ved hjælp af GC.Collect () -metoden. GC.Collect () -metoden er overbelastet - du kan ringe til den uden nogen parametre eller endda ved at videregive det generationsnummer, du gerne vil have til skraldesamleren at indsamle.

Bemærk, at objekter, der har færdiggørere (og hvis der ikke er foretaget et kald til SuppressFinalize-metoden), ikke ville blive indsamlet, når der foretages et opkald til GC.Collect () -metoden. Snarere placeres sådanne objekter i færdiggørelseskøen. Hvis du også vil samle disse objekter, skal du ringe til GC.WaitForPendingFinalizers () -metoden, så disse objekter ryddes op, når den næste GC-cyklus kører. I det væsentlige kræver genvinding af hukommelsen, der er optaget af objekter, der har finaliseringsprogrammer implementeret, to passeringer, da sådanne objekter placeres i færdiggørelseskøen i stedet for at blive genvundet i det første pass, når affaldssamleren kører.