Zbiralnik smeti (GC) je upravljalnik pomnilnika. Veliko programskih jezikov ima vgrajen GC. Ta funkcija samodejno dodeli in sprosti pomnilnik v programu. Sprosti vezan, neuporabljen pomnilnik, ki upočasni vašo aplikacijo.
Lepota GC je v tem, da sprosti pomnilnik v vašem imenu, ne da bi vam bilo treba storiti kar koli. Zato se vam lahko zdi tako pomembna lastnost, da bi pričakovali, da jo ima vsak programski jezik. Na žalost temu ni tako; celo popularen jezik, kot je C, lahko nima GC.
Kako deluje dodeljevanje pomnilnika?
Ko zaženete program v katerem koli programskem jeziku, vaš operacijski sistem rezervira a sklad podatkov v pomnilniku za ta program. Ta program ima v lasti in zaseda ta sklad podatkov, dokler ne zaključi izvajanja. Če vaš program potrebuje več pomnilnika, kot je na voljo, lahko dinamično dodeli več pomnilnika iz kopice pomnilnika operacijskega sistema.
V programiranju spremenljivka predstavlja pomnilniško lokacijo. Torej, ko deklarirate novo spremenljivko, programski jezik dodeli prostor v pomnilniku za to spremenljivko. Spremenljivka bo zdaj imela pomnilniški naslov. Dokler tej spremenljivki ne dodelite vrednosti, bo ostala neinicializirana in lahko vsebuje nekaj smeti.
Če vam programski jezik omogoča deklaracijo spremenljivke, ne da bi jo inicializirali, potem je to dinamična spremenljivka. To pomeni, da se lahko vrednost, ki jo dodelite spremenljivki, sčasoma spremeni. Vendar bo pomnilniška lokacija spremenljivke ostala enaka, dokler je ne sprostite.
Kako deluje sprostitev pomnilnika?
Dodeljevanje pomnilnika je podoben postopek za vse programske jezike. Toda ustrezna metoda sprostitve pomnilnika se ponavadi razlikuje. Obstajata dve vrsti metod za sprostitev pomnilnika; ročni in avtomatski. GC izvede samodejno sprostitev.
Razdelitev pomnilnika brez zbiralnika smeti
The Programski jezik C ne uporablja GC za sprostitev pomnilnika. Zato morajo programerji C ročno dodeljevati in sprostiti pomnilnik. C omogoča dinamično dodeljevanje pomnilnika, ko v času prevajanja ne veste, koliko pomnilnika boste uporabili med izvajanjem.
Standardna knjižnica (stdlib.h) vsebuje funkcije, ki jih C uporablja za upravljanje dinamičnega dodeljevanja pomnilnika. Te funkcije vključujejo:
- malloc(): dodeli določeno velikost pomnilnika in vrne kazalec na ta pomnilnik. Če v pomnilniškem področju operacijskega sistema ni na voljo dovolj pomnilnika, vrne vrednost null.
- free(): sprosti določen blok pomnilnika in ga vrne v pomnilniško področje operacijskega sistema.
Primer programa C
#vključujejo
#vključujejointglavni()
{
int *ptr; // deklariraj kazalec
int j; // deklariraj števec// dodeli prostor za 200 celih števil
ptr = (int *) malloc(200 * sizeof(int));// vstavimo celoštevilske vrednosti v dodeljeni pomnilnik
// in vsako vrednost natisni na konzolo
za (j = 0; j < 200; j++)
{
ptr[j] = j;
printf("%d\t",ptr[j]);
}
// sprostitev predhodno dodeljenega pomnilnika
prost(ptr);
vrnitev0;
}
Zgornja koda dodeli pomnilnik za shranjevanje 200 celih vrednosti z uporabo malloc() funkcijo. Za dostop do te pomnilniške lokacije uporablja kazalec in vanjo shrani 200 celih vrednosti. Kazalec tudi natisne podatke, shranjene na pomnilniški lokaciji, na konzolo. Končno program sprosti predhodno dodeljeni pomnilnik z uporabo prost() funkcijo.
Razdelitev pomnilnika z zbiralnikom smeti
Več priljubljenih programskih jezikov uporablja GC za upravljanje pomnilnika. To precej olajša življenje programerjev, ki uporabljajo te jezike. C# in Java sta dva programska jezika, ki uporabljata GC.
C# GC
V Programski jezik C#, GC upravlja dodeljevanje in sprostitev pomnilniških naslovov. Zato programerju C# ni treba skrbeti za sprostitev objekta, ko ta dokonča svoj namen.
C# GC inicializira pomnilniško področje, imenovano upravljana kopica, za vsak nov proces (ali program). Pokliče VirtualAlloc() funkcijo za dodeljevanje pomnilnika in VirtualFree() funkcijo za sprostitev. Najboljše pri tem je, da se vse to dogaja v ozadju in od vas, programerja, ni potreben noben napor.
C# GC ima motor za optimizacijo, ki ga uporablja za odločanje, kdaj sprostiti pomnilnik. Motor za optimizacijo pregleda koren aplikacije, da ugotovi, kateri objekti niso več v uporabi. To naredi tako, da ustvari graf, ki se razteza od korena aplikacije do povezanih objektov. Ta koren vključuje statična polja, lokalne spremenljivke itd. Vsak objekt, ki ni povezan s korenom aplikacije, je smeti.
Motor za optimizacijo GC ne zbira samo pomnilnika. Najprej mora obstajati nova zahteva za dodelitev pomnilnika. Če ima sistem malo razpoložljivega pomnilnika, bo v poštev stopil motor za optimizacijo GC.
Java GC
V Javi GC upravlja tudi dodeljevanje in sprostitev pomnilniških naslovov. Vendar ima Java trenutno štiri različne vrste podprtih zbiralnikov smeti:
- Najprej smeti (G1)
- Serijski
- Vzporedno
- Z zbiralnik smeti (ZGC)
Zbiralnik smeti G1 je Javin privzeti GC od izdaje Java Development Kit (JDK) 9. Java organizira podatke v objekte in te objekte shrani v kopico fiksne velikosti. Zbiralnik smeti G1 razdeli kopico na enako velika območja kopice. Nato je te regije kopice razdelil na dva dela; mlade in stare generacije.
Vsakič, ko ustvarite nov objekt, se v mladi generaciji zgodi dodelitev prostora za ta objekt. S postopkom staranja zbiralnik smeti G1 kopira predmete iz mladih regij v stare regije. Prav tako kopira predmete, ki so že v stari regiji, v starejšo regijo.
Zbiralnik smeti G1 nato izvede večino svoje sprostitve pomnilnika v mladi generaciji, občasno pa poseže v razdelek stare generacije.
Kakšne so prednosti zbiralnika smeti?
Prednost zbiralnika smeti je, da vam preprečuje, da bi med pisanjem kode razmišljali o upravljanju pomnilnika. To vam daje čas, da se osredotočite na druge pomembne vidike vaše prijave. Vendar je vredno poudariti več drugih prednosti.
Ponovna pridobitev neuporabljenih objektov in sprostitev pomnilnika zagotavljata čistejše izvajanje aplikacij. Če vaš program čim prej sprosti pomnilnik, bo imel manjši pomnilniški odtis in bo lahko deloval učinkoviteje.
Zbiranje smeti zmanjša napake, povezane z upravljanjem pomnilnika, kot so puščanja in napake kazalca. To je zato, ker proces ni več odvisen od programerja in njegove sposobnosti pisanja natančne kode.