Programovanie

Moje dva centy za slabé referencie v .Net

GC je schopný regenerovať pamäť obsadenú spravovanými objektmi. Mali by ste však podniknúť ďalšie opatrenia na uľahčenie zberu odpadu na zlepšenie výkonu vašich aplikácií.

Slabý odkaz je taký, ktorý odkazuje na objekt v pamäti a súčasne umožňuje zberaču odpadu zbierať objekt alebo kultivovať pamäť obsadenú objektom, keď je spustený GC. Objekt, ktorý je dosiahnuteľný, nie je odpadom zhromaždeným runtime.

Slabé referencie môžete použiť pre objekty, ktoré zaberajú veľa pamäte. Pri použití slabých odkazov na také objekty umožníte týmto objektom zhromažďovať odpadky a súčasne umožníte ich opätovné vytvorenie, ak to bude potrebné. Takže ak máte vo svojej aplikácii veľký objekt, ktorý by ste používali menej často, môžete na tieto objekty použiť slabý odkaz za predpokladu, že ich opätovné vytvorenie nie je také drahé.

Upozorňujeme, že keď vytvoríte slabý odkaz na objekt, IntPtr do GCHandle sa interne uloží pomocou slabého odkazu, ktorý ste vytvorili. Modul runtime používa tento server GCHandle na správu tabuľky, ktorá obsahuje slabé odkazy na objekty. Ak bol objekt už zhromaždený odpadkami, hodnota IntPtr bude IntPtr.Zero. Keď je slabý odkaz na objekt finalizovaný, zodpovedajúci záznam slabého odkazu na objekt v slabej referenčnej tabuľke je odstránený. Ak je slabý odkaz na objekt stále nažive a vyvoláte vlastnosť Target na slabom odkaze, vráti sa skutočný objekt, na ktorý ukazuje GCHandle slabého odkazu.

Vytvorenie slabého odkazu na objekt nezvyšuje životnosť objektu. Umožňuje zberaču odpadu získať späť pamäť obsadenú objektom, keď na tento objekt neexistujú silné odkazy. Rozdiel medzi slabým a silným odkazom na objekt je v tom, že zatiaľ čo prvý umožňuje zberaču odpadu získať späť pamäť obsadenú týmto objektom, silný odkaz na objekt neumožňuje zberačovi odpadu získať späť pamäť obsadenú ten objekt, ak je na neho dosiahnuteľný.

Programovanie slabej referencie v C #

Ak chcete vytvoriť slabú referenciu, musíte využiť výhody triedy System.WeakReference. Po vytvorení slabého odkazu na objekt môžete pomocou vlastnosti Target slabého odkazu, ktorý ste vytvorili, skontrolovať, či je pôvodný objekt stále nažive. Nasledujúci úryvok kódu ukazuje, ako môžete vytvoriť slabý odkaz na objekt.

Obdĺžnik obdĺžnika = nový Obdĺžnik (15, 10);

var slabáReferencia = nová slabáReferencia (obdĺžnik);

Vlastnosť IsAlive môžete použiť na kontrolu, či slabý odkaz na objekt je stále nažive. Toto je zoznam kódov, ktorý to ilustruje.

static void Main (reťazec [] args)

        {

Obdĺžnik obdĺžnika = nový Obdĺžnik (15, 10);

var slabáReferencia = nová slabáReferencia (obdĺžnik);

obdĺžnik = null;

bool isAlive = strongReference.IsAlive;

if (isAlive)

Console.WriteLine ("Objekt je stále nažive");

Console.Read ();

        }

Ak silný odkaz na objekt už nie je k dispozícii, môžete využiť vlastnost Target slabého odkazu na použitie objektu tak, ako je to znázornené v útržku kódu uvedenom nižšie.

bool isAlive = strongReference.IsAlive;

if (isAlive)

{

Obdĺžnik obdĺžnika = slabýReferencia. Cieľ ako Obdĺžnik;

// Teraz môžete použiť obdĺžnikový objekt ako obvykle

}

Krátke a dlhé trvanie slabých referencií

Slabé referencie môžu byť buď krátkodobé, alebo dlhodobé. Primárny rozdiel medzi krátkym a slabým odkazom je v tom, že zatiaľ čo v prvom prípade sa vlastnosť Target slabého odkazu stane nulovou, ak GC znovu získa objekt, v druhom prípade bude dlhá slabá referencia živá aj po spustení GC, tj. prežíva GC cyklus. Upozorňujeme, že dlhé slabé referencie by ste mali používať opatrne, pretože po dokončení nie je možné predvídať stav objektu.

V zásade by ste mali použiť krátke slabé referencie, keď chcete použiť objekt, ktorý je v použiteľnom stave. Naopak, dlhá slabá referencia je dobrou voľbou, keď chcete objekt použiť bez ohľadu na jeho stav. Ak chcete vytvoriť dlhú slabú referenciu, musíte pri vytváraní slabej referencie odovzdať „true“ ako druhý parameter preťaženému konštruktoru triedy WeakReference. Ilustruje to nasledujúci úryvok kódu.

Obdĺžnik obdĺžnika = nový Obdĺžnik (15, 10);

var slabReference = nový WeakReference (obdĺžnik, pravda);