Programovanie

Moje dva centy v metóde GC. Collect v C #

Metóda GC.Collect () je už dlho populárna medzi vývojármi .Net. Málokto z nás však vie, ako to v skutočnosti funguje, alebo či je vôbec potrebné zavolať na ňu.

CLR (Common Language Runtime) prijíma zber odpadu ako mechanizmus na vyčistenie zdrojov spotrebovaných vašou aplikáciou. Upozorňujeme, že keď vytvárate objekty v .Net, ukladajú sa do spravovanej haldy a po dokončení ich používania sa nemusíte starať o ich čistenie - runtime by to urobil za vás.

CLR organizuje spravovanú hromadu na generácie. Tri generácie, do ktorých je spravovaná halda organizovaná, sú: Generácia 0, Generácia 1 a Generácia 2. GC je schopný zrekultivovať pamäť obsadenú spravovanými objektmi. Mali by ste však postupovať podľa určitých pokynov, aby ste uľahčili rýchlejší zber odpadu, aby ste zlepšili výkon svojej aplikácie.

Mám použiť metódu GC.Collect ()?

Najprv musíte vôbec zavolať spoločnosti GC.Collect v kóde svojej aplikácie? Odpoveď je vo väčšine prípadov nie. Teraz vám poviem, čo táto metóda robí a prečo by ste sa vo väčšine prípadov nemali tejto metódy dovolávať.

Keď zavoláte metódu GC.Collect (), prevádzkové prostredie vykoná prechádzanie zásobníka, aby určilo dosiahnuteľné objekty a tie, ktoré nie sú. Tiež zmrazí hlavné vlákno (a tiež všetky podradené vlákna, ktoré vytvoril) aplikácie. Inými slovami, pri volaní metódy GC.Collect () runtime vykoná blokovanie zhromažďovania odpadkov všetkých generácií.

Vždy by som radšej nepoužíval GC.Collect (), pokiaľ na to neexistuje konkrétny dôvod. GC sa zvyčajne skladá z fázy Mark a Sweep, po ktorých nasleduje fáza zhutnenia. Čas, ktorý modul runtime strávi vykonaním GC, sa môže stať prekážkou, takže ho používajte iba veľmi zriedka a ak to naozaj potrebujete. Rico Mariani tvrdí: „Zvážte volanie GC.Collect (), ak sa práve stala nejaká neopakujúca sa udalosť a táto udalosť s vysokou pravdepodobnosťou spôsobila smrť mnohých starých objektov.“

Pomocou metódy GC.Collect ()

Tu je príklad, ako môžete vo svojom kóde vyvolať metódu GC.Collect ().

GC.Collect ();

Upozorňujeme, že môžete zhromažďovať aj objekty, ktoré sa týkajú konkrétnej generácie.

GC.Collect () - slúži na zber predmetov prítomných v generáciách 0, 1, 2

GC.Collect (0) - slúži na zhromažďovanie predmetov prítomných v generácii 0

GC.Collect (1) - slúži na zber predmetov prítomných v generáciách 0 a

Môžete tiež určiť, koľko pamäte sa uvoľnilo, pomocou volania metódy GC.Collect (). Môžete to urobiť tak, že využijete metódu System.GC.GetTotalMemory () uvedenú v útržku kódu nižšie.

// Sem napíš kód, aby si vytvoril nejaké veľké objekty

Console.WriteLine ("Celková dostupná pamäť pred zhromaždením: {0: N0}", System.GC.GetTotalMemory (false));

System.GC.Collect ();

Console.WriteLine ("Celková dostupná pamäť: {0: N0}", System.GC.GetTotalMemory (true));

Metódu GC.GetGeneration () možno použiť na zistenie generácie, do ktorej objekt patrí. Prečítajte si zoznam kódov uvedený nižšie.

static void Main (reťazec [] args)

       {

List obj = new List () {"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 ();

       }

Po vykonaní vyššie uvedeného programu sa v okne konzoly vytlačí nasledujúci text.

0

1

2

Ako vidíte, každé volanie metódy GC.Collect () propaguje objekt „obj“ na ďalšiu vyššiu generáciu. Je to preto, že objekt „obj“ prežije zber odpadu v každom z dvoch prípadov, t. J. Nie je kultivovaný v žiadnom z dvoch hovorov uskutočnených metódou GC.Collect ().

Odpadky môžete vynútiť buď pre všetky tri generácie, alebo pre konkrétnu generáciu pomocou metódy GC.Collect (). Metóda GC.Collect () je preťažená - môžete ju zavolať bez akýchkoľvek parametrov alebo dokonca tak, že odovzdáte generačné číslo, ktoré chcete zberateľovi odpadu zhromaždiť.

Upozorňujeme, že objekty, ktoré majú finalizátory (a ak nebolo uskutočnené volanie metódy SuppressFinalize), by sa pri uskutočňovaní volania metódy GC.Collect () nezhromaždili. Takéto objekty by sa skôr umiestnili do finalizačného frontu. Ak by ste chceli zhromaždiť aj tieto objekty, budete musieť zavolať metódu GC.WaitForPendingFinalizers (), aby sa tieto objekty pri ďalšom cykle GC vyčistili. V podstate regenerácia pamäte obsadenej objektmi, ktoré majú implementované finalizátory, vyžaduje dva priechody, pretože tieto objekty sú umiestnené skôr do finalizačného frontu, než aby boli znovu získané v prvom prechode, keď je spustený zberač odpadu.

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