A szemétgyűjtő (GC) egy memóriakezelő. Sok programozási nyelv rendelkezik beépített GC-vel. Ez a szolgáltatás automatikusan lefoglalja és felszabadítja a program memóriáját. Felszabadítja a lekötött, fel nem használt memóriát, ami lelassítja az alkalmazást.
A GC szépsége az, hogy felszabadítja a memóriát az Ön nevében, anélkül, hogy bármit is tenne. Ezért olyan alapvető tulajdonságnak tekintheti, hogy azt minden programozási nyelven elvárhatja. Sajnos ez nem így van; még egy olyan népszerű nyelvből is, mint a C, hiányozhat a GC.
Hogyan működik a memóriafoglalás?
Amikor egy programot bármely programozási nyelven futtat, az operációs rendszer fenntartja a adathalom a memóriában ahhoz a programhoz. Ez a program birtokolja és elfoglalja ezt az adathalmot, amíg be nem fejezi a végrehajtást. Ha a programnak több memóriára van szüksége, mint amennyi rendelkezésre áll, akkor dinamikusan több memóriát foglalhat le az operációs rendszer memóriakupacjából.
A programozásban egy változó egy memóriahelyet jelöl. Tehát, amikor deklarál egy új változót, a programozási nyelv helyet foglal a memóriában ennek a változónak. A változónak most lesz memóriacíme. Amíg nem rendel hozzá értéket ehhez a változóhoz, az inicializálatlan marad, és előfordulhat, hogy tartalmaz néhány szemét értéket.
Ha egy programozási nyelv lehetővé teszi, hogy egy változót inicializálás nélkül deklaráljunk, akkor az egy dinamikus változó. Ez azt jelenti, hogy a változóhoz rendelt érték idővel változhat. A változó memóriahelye azonban mindaddig változatlan marad, amíg fel nem oldja.
Hogyan működik a memóriafelosztás?
A memóriafoglalás minden programozási nyelvhez hasonló folyamat. De a memóriafelszabadítás megfelelő módszere eltérő. Kétféle memóriafelszabadítási módszer létezik; kézi és automata. A GC automatikus felosztást végez.
Memóriafelosztás szemétgyűjtő nélkül
Az C programozási nyelv nem használ GC-t a memória felszabadítására. Ezért a C programozóknak manuálisan kell lefoglalniuk és felszabadítaniuk a memóriát. A C lehetővé teszi a dinamikus memóriafoglalást, ha nem tudja a fordítási időben, hogy mennyi memóriát fog használni futási időben.
A szabványos könyvtár (stdlib.h) tartalmazza azokat a függvényeket, amelyeket a C a dinamikus memóriafoglalás kezelésére használ. Ezek a funkciók a következők:
- malloc(): egy adott méretű memóriát foglal le, és egy mutatót ad vissza erre a memóriára. Ha nem áll rendelkezésre elegendő memória az operációs rendszer memóriatárában, nullát ad vissza.
- free(): felszabadít egy adott memóriablokkot, és visszaadja az operációs rendszer memóriakészletébe.
C Programpélda
#tartalmazza
#tartalmazzaintfő-()
{
int *ptr; // mutató deklarálása
int j; // deklarálja a számlálót// helyet foglal 200 egész szám számára
ptr = (int *) malloc(200 * mérete(int));// egész számok beszúrása a lefoglalt memóriába
// és minden értéket kinyomtat a konzolra
számára (j = 0; j < 200; j++)
{
ptr[j] = j;
printf("%d\t",ptr[j]);
}
// felszabadítja a korábban lefoglalt memóriát
ingyenes(ptr);
Visszatérés0;
}
A fenti kód memóriát foglal le 200 egész érték tárolására a malloc() funkció. Egy pointer segítségével éri el ezt a memóriahelyet, és 200 egész értéket tárol benne. A mutató a memóriahelyen tárolt adatokat is kinyomtatja a konzolra. Végül a program felszabadítja a korábban lefoglalt memóriát a ingyenes() funkció.
Memória felosztása szemétgyűjtővel
Számos népszerű programozási nyelv használ GC-t a memóriakezeléshez. Ez jelentősen megkönnyíti azoknak a programozóknak az életét, akik ezeket a nyelveket használják. A C# és a Java két programozási nyelv, amelyek GC-t használnak.
A C# GC
Ban,-ben C# programozási nyelv, egy GC kezeli a memóriacímek kiosztását és felszabadítását. Ezért a C# programozónak nem kell aggódnia egy objektum felszabadítása miatt, miután az elérte a célját.
A C# GC minden új folyamathoz (vagy programhoz) inicializál egy memóriakészletet, amelyet menedzselt kupacnak neveznek. Úgy hívja a VirtualAlloc() funkció a memória lefoglalására és a VirtualFree() funkciót annak felszabadítására. A legjobb az egészben az, hogy mindez a háttérben történik anélkül, hogy öntől, a programozótól erőfeszítést igényelne.
A C# GC rendelkezik egy optimalizáló motorral, amivel eldönti, hogy mikor szabad felszabadítani a memóriát. Az optimalizáló motor megvizsgálja az alkalmazás gyökerét, hogy megállapítsa, mely objektumok már nincsenek használatban. Ezt úgy teszi meg, hogy létrehoz egy gráfot, amely az alkalmazás gyökerétől a csatlakoztatott objektumokig terjed. Ez a gyökér statikus mezőket, helyi változókat stb. Minden olyan objektum, amely nem kapcsolódik az alkalmazás gyökeréhez, hulladék.
A GC optimalizáló motor nem csak önmagában gyűjti a memóriát. Először egy új memóriafoglalási kérelemnek kell lennie. Ha a rendszerben kevés a szabad memória, akkor a GC optimalizáló motor lép működésbe.
A Java GC
Java nyelven a GC kezeli a memóriacímek kiosztását és felszabadítását is. Azonban a Java jelenleg négy különböző típusú támogatott szemétgyűjtővel rendelkezik:
- Szemét-első (G1)
- Sorozatszám
- Párhuzamos
- Z szemétgyűjtő (ZGC)
A G1 szemétgyűjtő a Java alapértelmezett GC-je a Java Development Kit (JDK) 9 kiadása óta. A Java objektumokba rendezi az adatokat, és ezeket az objektumokat egy rögzített méretű kupacban tárolja. A G1 szemétgyűjtő a kupacot egyenlő méretű kupacterületekre osztja. Ezután ezeket a kupacterületeket két részre osztotta; fiatal és idős generációk.
Minden alkalommal, amikor új objektumot hoz létre, az objektum számára helykiosztás történik a fiatal generációban. A G1 szemétgyűjtő egy öregedési folyamat segítségével a fiatal régiókban lévő objektumokat a régi régiókra másolja. A már a régi régióban lévő objektumokat is átmásolja egy régebbi régióba.
A G1 szemétgyűjtő ezután a legtöbb memóriafelszabadítást a fiatal generációban végzi, időnként bemerészkedik a régi generációhoz.
Milyen előnyei vannak a szemétgyűjtőnek?
A szemétgyűjtő előnye, hogy megakadályozza, hogy a memóriakezelésre gondoljon a kód írása közben. Ez időt ad arra, hogy az alkalmazás egyéb fontos szempontjaira összpontosítson. Azonban számos egyéb előnyt is érdemes kiemelni.
A nem használt objektumok visszanyerése és a memória felszabadítása tisztább alkalmazás-végrehajtást tesz lehetővé. Ha a program a lehető leghamarabb felszabadítja a memóriát, kisebb lesz a memóriaterület, és hatékonyabban tud futni.
A szemétgyűjtés csökkenti a memóriakezeléssel kapcsolatos hibákat, például a szivárgásokat és a mutatóhibákat. Ennek az az oka, hogy a folyamat már nem függ a programozótól és a pontos kód írási képességétől.