Programiranje

Moja dva centa na GC. Zberi metodo v C #

Metoda GC.Collect () je že dolgo priljubljena med razvijalci .Net. Vendar le redki izmed nas vedo, kako to dejansko deluje, ali če je klic sploh potreben.

CLR (Common Language Runtime) zbiranje smeti sprejme kot mehanizem za čiščenje virov, ki jih porabi vaša aplikacija. Ko ustvarite predmete v .Netu, se shranijo v upravljani kup in ko jih končate, vam ni treba skrbeti za njihovo čiščenje - izvajalno okolje bi to storilo namesto vas.

CLR organizira upravljano kopico v generacije. Tri generacije, v katere je organiziran upravljani kup, so: generacija 0, generacija 1 in generacija 2. GC je spreten pri pridobivanju pomnilnika, ki ga zasedajo upravljani predmeti. Vendar morate upoštevati določene smernice, da olajšate hitrejše zbiranje smeti in tako izboljšate delovanje aplikacije.

Ali naj uporabim metodo GC.Collect ()?

Najprej morate sploh poklicati GC. Zbrati kodo svoje aplikacije? Odgovor je v večini primerov ne. Naj vam zdaj povem, kaj ta metoda počne in zakaj bi se v večini primerov morali vzdržati klica te metode.

Ko pokličete metodo GC.Collect (), izvajalno okolje izvede sprehod skladbe, da določi predmete, ki so dosegljivi, in tiste, ki niso. Prav tako zamrzne glavno nit (in tudi vse podrejene niti, ki jih je ustvaril) aplikacije. Z drugimi besedami, ko je klicana metoda GC.Collect (), izvajalno okolje blokira zbiranje smeti vseh generacij.

Vedno raje ne bi uporabljal GC.Collect (), razen če obstaja poseben razlog za njegovo uporabo. GC je običajno sestavljen iz faz Mark in Sweep, ki ji sledi faza zbijanja. Čas, porabljen za izvajanje GC, lahko postane ozko grlo, zato ga uporabljajte le zelo redko in če res potrebujete. Rico Mariani pravi: "Razmislite o klicanju GC.Collect (), če se je pravkar zgodil kakšen neponavljajoč se dogodek in je zaradi tega dogodka verjetno umrlo veliko starih predmetov."

Z uporabo metode GC.Collect ()

Tukaj je opisano, kako lahko v svoji kodi prikličete metodo GC.Collect ().

GC.Collect ();

Upoštevajte, da lahko zbirate tudi predmete, ki se nanašajo na določeno generacijo.

GC.Collect () - uporablja se za zbiranje predmetov, prisotnih v generacijah 0, 1, 2

GC.Collect (0) - uporablja se za zbiranje predmetov, prisotnih v generaciji 0

GC.Collect (1) - uporablja se za zbiranje predmetov, prisotnih v generacijah 0 in

Določite lahko tudi, koliko pomnilnika je bilo sproščenega, tako da pokličete metodo GC.Collect (). Če želite to narediti, lahko izkoristite metodo System.GC.GetTotalMemory (), kot je prikazano v spodnjem delčku kode.

// Napišite kodo, če želite tukaj ustvariti nekaj velikih predmetov

Console.WriteLine ("Skupno razpoložljiv pomnilnik pred zbiranjem: {0: N0}", System.GC.GetTotalMemory (false));

System.GC.Collect ();

Console.WriteLine ("Skupna zbirka razpoložljivega pomnilnika: {0: N0}", System.GC.GetTotalMemory (true));

Z metodo GC.GetGeneration () lahko poznamo generacijo, ki ji pripada objekt. Glejte spodnji seznam kod.

statična praznina Main (string [] args)

       {

Seznam obj = nov seznam () {"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 ();

       }

Ko zaženete zgornji program, je tukaj tiskano v oknu konzole.

0

1

2

Kot lahko vidite, vsak klic metode GC.Collect () promovira objekt "obj" v naslednjo višjo generacijo. To je zato, ker objekt "obj" preživi zbiranje smeti v obeh primerih, torej ni povrnjen v nobenem od dveh klicev, opravljenih z metodo GC.Collect ().

Z metodo GC.Collect () lahko vsilite odvoz smeti bodisi na vse tri generacije bodisi na določeno generacijo. Metoda GC.Collect () je preobremenjena - pokličete jo lahko brez kakršnih koli parametrov ali celo tako, da zbiralcu smeti posredujete številko generacije, ki jo želite zbrati.

Upoštevajte, da predmeti, ki imajo zaključevalnike (in če klic metode SuppressFinalize ni bil izveden), ne bodo zbrani, ko bo opravljen klic metode GC.Collect (). Takšni predmeti bi bili postavljeni v čakalno vrsto za dokončanje. Če bi radi zbrali tudi te predmete, bi morali poklicati metodo GC.WaitForPendingFinalizers (), da se ti predmeti očistijo, ko se zažene naslednji cikel GC. V bistvu je za povrnitev pomnilnika, ki ga zasedajo predmeti, v katerih so izvedeni zaključevalniki, potrebna dva prehoda, saj so taki predmeti postavljeni v čakalno vrsto za dokončanje, namesto da bi bili ponovno zasedeni v prvem prehodu, ko se zbiralec smeti izvaja.

$config[zx-auto] not found$config[zx-overlay] not found