Programiranje

Moja dva centa na šibke reference v .Net

GC spretno pridobiva pomnilnik, ki ga zasedajo upravljani predmeti. Vendar bi morali sprejeti dodatne ukrepe za lažje zbiranje smeti za izboljšano delovanje vaših aplikacij.

Šibka referenca je tista, ki se sklicuje na objekt v pomnilniku, hkrati pa zbiralcu smeti omogoča, da zbere predmet ali povrne pomnilnik, ki ga zaseda objekt, ko se GC zažene. Dosegljiv predmet ni smeti, ki jih zbere runtime.

Šibke reference lahko uporabite za predmete, ki porabijo veliko pomnilnika. Z uporabo šibkih referenc za take predmete omogočite, da se ti predmeti zbirajo v smeti, hkrati pa omogočite, da se ti predmeti po potrebi znova ustvarijo pozneje. Torej, če imate v svoji aplikaciji velik predmet, ki bi ga uporabljali redkeje, lahko uporabite šibko sklicevanje na take predmete, če njihova ponovna izdelava ni tako draga.

Ko ustvarite šibek sklic na objekt, šibki sklic, ki ste ga ustvarili, interno shrani IntPtr na GCHandle. Izvajalno okolje uporablja ta GCHandle za upravljanje tabele, ki vsebuje šibke sklice na predmete. Če je bil predmet že zbran smeti, bo vrednost IntPtr IntPtr.Zero. Ko je šibka referenca na objekt dokončana, se ustrezen vnos šibke reference na objekt v tabeli šibkih referenc odstrani. Če je šibka referenca na objekt še vedno živa in na šibki referenci prikličete lastnost Target, se vrne dejanski objekt, na katerega kaže GCHandle šibkega sklica.

Ustvarjanje šibke reference na predmet ne poveča življenjske dobe predmeta. Zbiratelju smeti lahko povrne pomnilnik, ki ga zaseda objekt, kadar na njega ne obstajajo močne reference. Razlika med šibkim in močnim sklicevanjem na predmet je v tem, da medtem ko prvi še vedno omogoča zbiralcu smeti, da si povrne pomnilnik, ki ga zaseda ta objekt, močan sklic na predmet ne omogoča zbiralcu smeti, da si povrne pomnilnik ta predmet, če je predmet dosegljiv.

Programiranje šibke reference v jeziku C #

Če želite ustvariti šibko referenco, bi morali izkoristiti razred System.WeakReference. Ko ustvarite šibko referenco na predmet, lahko z lastnostjo Target šibke reference, ki ste jo ustvarili, preverite, ali je prvotni objekt še živ. Naslednji delček kode prikazuje, kako lahko ustvarite šibek sklic na predmet.

Pravokotnik pravokotnik = nov pravokotnik (15, 10);

var šibkaReferenca = nova WeakReference (pravokotnik);

Z lastnostjo IsAlive lahko preverite, ali je šibka referenca na objekt še vedno živa. Tu je seznam kode, ki to ponazarja.

statična praznina Main (string [] args)

        {

Pravokotnik pravokotnik = nov pravokotnik (15, 10);

var šibkoReferenca = nova WeakReference (pravokotnik);

pravokotnik = nič;

bool isAlive = šibkaReference.IsAlive;

če (isAlive)

Console.WriteLine ("Predmet je še vedno živ");

Console.Read ();

        }

Če močna referenca na objekt ni več na voljo, lahko s pomočjo lastnosti Target šibke reference uporabite objekt, kot je prikazano v spodnjem delčku kode.

bool isAlive = šibkaReference.IsAlive;

če (isAlive)

{

Pravokotnik pravokotnik = šibkaReference.Ciljaj kot pravokotnik;

// Predmet pravokotnika lahko zdaj uporabljate kot običajno

}

Kratke in dolgo živele šibke reference

Šibke reference so lahko kratkotrajne ali dolgotrajne. Primarna razlika med kratkim in šibkim sklicem je, da medtem ko v prvem primeru lastnost Target šibkega sklica postane nična, če GC ponovno pridobi objekt, je v drugem primeru dolgi šibki sklic živ tudi po zagonu GC, tj. preživi cikel GC. Upoštevajte, da morate previdno uporabljati dolge šibke reference, saj stanja predmeta po dokončanju ni mogoče predvideti.

V bistvu uporabite kratke šibke reference, če želite uporabiti predmet, ki je v uporabnem stanju. Nasprotno, dolga šibka referenca je dobra izbira, če bi radi uporabili predmet ne glede na njegovo stanje. Če želite ustvariti dolg šibki sklic, morate med ustvarjanjem šibkega sklica predati »true« kot drugi parameter preobremenjenemu konstruktorju razreda WeakReference. Naslednji delček kode to ponazarja.

Pravokotnik pravokotnik = nov pravokotnik (15, 10);

var šibkoReferenca = nova WeakReference (pravokotnik, resnično);

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