Programavimas

Geriausia praktika naudojant „Disject and Final“ .Net

„Microsoft .Net Framework“ teikia šiukšlių surinkėją, kuris veikia fone ir atleidžia atmintį, kurią užima valdomi objektai, kai jie nebėra nurodyti jūsų kode. Nors šiukšlių surinkėjas puikiai išvalo valdomų objektų užimamą atmintį, nėra garantuojama, kad nevaldomų objektų užimama atmintis bus išvalyta, kai bus vykdomas kitas GC ciklas. Jei jūsų programoje yra nevaldomų išteklių, turėtumėte užtikrinti, kad tokius išteklius išleisite aiškiai, kai baigsite juos naudoti. Šiame straipsnyje aš pabrėžiu geriausią praktiką, kurios turėtumėte laikytis, kad išvalytumėte savo programoje naudojamus išteklius.

GC naudoja kartas, kad išlaikytų ir valdytų santykinį atmintyje sukurtų objektų tarnavimo laiką. Nauji sukurti objektai yra 0 kartoje. Pagrindinė prielaida yra ta, kad naujai sukurto objekto gyvenimo laikas gali būti trumpesnis, o seno objekto - ilgesnis. Kai objektai, gyvenantys 0 kartoje, nėra atgaunami po GC ciklo, jie perkeliami į 1 kartą. Panašiai, jei objektai, gyvenantys 1 kartoje, išgyvena GC valymą, jie perkeliami į 2 kartą. Atkreipkite dėmesį, kad GC veikia dažniau žemesniosios kartos, kad aukštesnėse. Taigi objektai, gyvenantys 0 kartoje, būtų valomi dažniau, palyginti su objektais, esančiais 1 kartoje. Taigi, geresnė programavimo praktika yra užtikrinti, kad jūs naudojate daugiau vietinių objektų, kurie yra didesnės apimties objektai, kad objektai nebūtų perkelti aukštesnėms kartoms.

Atminkite, kad kai jūsų klasėje yra destruktorius, vykdymo laikas tai laiko „Finalize“ () metodu. Kadangi užbaigimas yra brangus, naikintuvus turėtumėte naudoti tik prireikus - kai turite savo klasėje išteklių, kuriuos turėtumėte išvalyti. Kai jūsų klasėje yra baigtinis, tų klasių objektai perkeliami į užbaigimo eilę. Jei objektai yra pasiekiami, jie perkeliami į „Freachable“ eilę. GC susigrąžina atmintį, kurią užima objektai, kurių negalima pasiekti. Periodiškai GC tikrina, ar pasiekiami objektai, esantys „Freachable“ eilėje. Jei jų pasiekti negalima, atgaunama tų objektų užimama atmintis. Taigi akivaizdu, kad objektams, esantiems „Neįmanoma“ eilėje, reikės daugiau laiko, kad šiukšlių surinkėjas išvalytų. Tai yra bloga praktika, kai jūsų C # klasėje yra tuščių naikintuvų, nes tokių klasių objektai būtų perkelti į užbaigimo eilę ir, jei reikia, į „Neįmanoma“.

Galutinė versija yra netiesiogiai iškviečiama, kai atgaunama objekto užimama atmintis. Vis dėlto GC negarantuoja, kad bus iškviestas finalistas - gali būti, kad jo apskritai nebus. Iš esmės užbaigimo programa veikia nedeterministiniu režimu - vykdymo laikas negarantuoja, kad baigiamasis asmuo apskritai bus iškviestas. Vis dėlto galite priversti iškviesti finalistą, nors tai visai nėra gera praktika, nes yra susijusios nuobaudos už atlikimą. Finalistai visada turėtų būti apsaugoti ir visada naudojami tik tvarkomiems ištekliams išvalyti. Niekada neturėtumėte skirti atminties užbaigimo programoje, rašyti kodą, kad būtų užtikrinta gijų sauga, arba naudoti virtualiuosius metodus iš užbaigimo priemonės.

Kita vertus, „Dispose“ metodas suteikia „deterministinį išvalymą“, kaip išvalyti išteklius .NET. Tačiau metodas „Išmesti“, skirtingai nei baigiamasis, turėtų būti vadinamas aiškiai. Jei turite klasėje apibrėžtą šalinimo metodą, turėtumėte įsitikinti, kad jis yra iškviestas. Taigi, šalinimo metodas turėtų būti aiškiai vadinamas kliento kodu. Bet ką daryti, jei pamiršote paskambinti „Dispose“ metodu, kurį atskleidė klasė, naudojanti nevaldomus išteklius? Klasės, diegiančios IDisposable sąsają, klientai turėtų aiškiai iškviesti metodą Dispose. Tokiu atveju turite paskambinti „Dispose“ iš užbaigimo programos. Ši automatinio deterministinio užbaigimo strategija užtikrina, kad jūsų kode naudojami nevaldomi ištekliai bus išvalyti.

Turėtumėte įdiegti IDisposable kiekvienam tipui, kuriame yra užbaigimo priemonė. Rekomenduojama taikyti ir „Dispose“, ir „Finalize“, kai savo klasėje turite nevaldomų išteklių.

Šis kodo fragmentas parodo, kaip galite įdiegti „Dispose Finalize“ modelį C #.

apsaugotas virtualus negaliojantis šalinimas („Bool“ šalinimas)

        {

jei (atsikratyti)

            {

// rašyti kodą tvarkant valdomus objektus

            }

// rašykite kodą, kad išvalytumėte nevaldomus objektus ir išteklius

        }

Šis parametruojamas šalinimo metodas gali būti automatiškai iškviestas iš destruktoriaus, kaip parodyta žemiau esančiame kodo fragmente.

~ Ištekliai ()

        {

jei (! pašalinta)

            {

disponuoti = tiesa;

Sunaikinti (klaidinga);

            }

        }