Ohjelmointi

Parhaat käytännöt Hävitä ja viimeistele .Net -palvelussa

Microsoft .Net Framework tarjoaa roskakorin, joka toimii taustalla ja vapauttaa hallittujen objektien käyttämän muistin, kun niihin ei enää viitata koodissasi. Vaikka roskien keräilijä osaa puhdistaa hallittujen objektien käyttämän muistin, ei voida taata, että hallitsemattomien objektien käyttämä muisti puhdistettaisiin seuraavan GC-syklin suorituksen yhteydessä. Jos sovelluksessasi on hallitsemattomia resursseja, varmista, että vapautat resurssit nimenomaisesti, kun olet lopettanut niiden käytön. Tässä artikkelissa korostan parhaita käytäntöjä, joita sinun tulisi noudattaa sovelluksessasi käytettyjen resurssien siivoamiseksi.

GC käyttää sukupolvia ylläpitää ja hallita muistiin luotujen objektien suhteellista käyttöikää. Uusina luodut objektit sijoitetaan sukupolvelle 0. Perusoletus on, että uudella luodulla objektilla voi olla lyhyempi käyttöikä, kun taas vanhalla objektilla voi olla pidempi elinikä. Kun sukupolvessa 0 asuvia esineitä ei saada takaisin GC-syklin jälkeen, ne siirretään sukupolvelle 1. Vastaavasti, jos 1. sukupolvessa olevat objektit selviävät GC-siivouksesta, ne siirretään sukupolvelle 2. Huomaa, että GC toimii useammin alemmilla sukupolvilla kuin ylemmillä. Joten objektit, jotka asuvat sukupolvessa 0, puhdistettaisiin useammin kuin objektit, jotka asuvat sukupolvessa 1. Joten on parempi ohjelmointikäytäntö varmistaa, että käytät enemmän paikallisia objekteja, jotka objektit ovat korkeammalla, jotta vältetään esineiden siirtäminen korkeammille sukupolville.

Huomaa, että kun luokassasi on destruktori, ajonaikainen se käsittelee sitä Finalize () -metodina. Koska viimeistely on kallista, sinun tulee käyttää tuhoajia vain tarvittaessa - kun sinulla on luokassa resursseja, jotka sinun on puhdistettava. Kun luokassasi on viimeistelijä, näiden luokkien objektit siirretään viimeistelyjonoon. Jos kohteisiin pääsee käsiksi, ne siirretään "Freachable" -jonoon. GC palauttaa muistin, joka on sellaisten esineiden käytössä, joihin ei ole yhteyttä. GC tarkistaa säännöllisin väliajoin, ovatko "Freachable" -jonossa olevat objektit tavoitettavissa. Jos ne eivät ole tavoitettavissa, kyseisten esineiden käyttämä muisti palautetaan. Joten on ilmeistä, että "Freachable" -jonossa olevat esineet tarvitsevat enemmän aikaa puhdistettavaksi roskakoriin. On huono käytäntö, että C # -luokassasi on tyhjiä tuhoajia, koska tällaisten luokkien objektit siirretään viimeistelyjonoon ja tarvittaessa "Freachable" -jonoon.

Viimeistelijää kutsutaan implisiittisesti, kun objektin käyttämä muisti otetaan takaisin. Viimeistelylaitetta ei kuitenkaan voida taata kutsumaan GC: lle - sitä voidaan kutsua tai ei voida kutsua ollenkaan. Pohjimmiltaan viimeistelijä toimii ei-deterministisessä tilassa - ajonaika ei takaa, että viimeistelijä kutsutaan ollenkaan. Voit kuitenkin pakottaa viimeistelijän kutsumaan, vaikka se ei ole ollenkaan hyvä käytäntö, koska siihen liittyy rangaistuksia. Viimeistelijät tulisi aina suojata, ja niitä tulisi aina käyttää vain hallittujen resurssien puhdistamiseen. Sinun ei koskaan pidä jakaa muistia viimeistelylaitteen sisällä, kirjoittaa koodia säikeiden turvallisuuden toteuttamiseksi tai käyttää virtuaalisia menetelmiä viimeistelylaitteessa.

Hävitysmenetelmä toisaalta tarjoaa "deterministisen puhdistuksen" lähestymistavan resurssien puhdistamiseen .Netissä. Hävitä-menetelmää, toisin kuin viimeistelylaite, tulisi kuitenkin kutsua nimenomaisesti. Jos sinulla on luokassa määritelty Hävitä-menetelmä, varmista, että sitä kutsutaan. Joten asiakastunnuksen tulisi kutsua nimenomaisesti Dispose-menetelmä. Mutta entä jos unohdat kutsua Hävitä-menetelmää, joka altistuu hallitsemattomia resursseja käyttävälle luokalle? IDisposable-käyttöliittymän toteuttavan luokan instanssin asiakkaiden tulisi kutsua Dispose-menetelmä nimenomaisesti. Tässä tapauksessa sinun on soitettava viimeistelijän sisäpuolelta Hävitä. Tämä automaattinen deterministinen viimeistelystrategia varmistaa, että koodissasi käytetyt hallitsemattomat resurssit puhdistetaan.

Sinun tulisi ottaa käyttöön IDisposable kaikille tyyppeille, joilla on viimeistelijä. On suositeltavaa toteuttaa sekä Hävitä että Viimeistele, kun luokassa on hallitsemattomia resursseja.

Seuraava koodinpätkä kuvaa, kuinka voit poistaa Hävitä viimeistellä -mallin C #: ssä.

suojattu virtuaalinen tyhjiö Hävitä (bool-hävitys)

        {

jos (hävittäminen)

            {

// kirjoita koodi siivoamaan hallitut objektit

            }

// kirjoita koodi puhdistamaan hallitsemattomat objektit ja resurssit

        }

Tätä parametrisoitua Hävitä-menetelmää voidaan kutsua automaattisesti tuhoajasta alla olevan koodinpätkän mukaisesti.

~ Resurssit ()

        {

jos (! hävitetään)

            {

disposed = tosi;

Hävitä (väärä);

            }

        }