garbage collection (tsz. garbage collections)
A szemétgyűjtés (garbage collection, GC) egy automatikus memória-kezelési folyamat, amely eltávolítja a már nem használt, elérhetetlen memóriaterületeket egy program futása során. A célja az, hogy megakadályozza a memória-szivárgást és optimalizálja az erőforrások használatát.
A szemétgyűjtést általában magasabb szintű programozási nyelvek használják, mint például: - Java - C# - Python - JavaScript - Go
A C és C++ viszont nem rendelkezik beépített szemétgyűjtővel, ezért itt a programozónak manuálisan kell lefoglalnia (new
, malloc()
) és felszabadítania (delete
, free()
) a memóriát.
A programok futás közben folyamatosan memóriát foglalnak le objektumok és adatok számára. Ha ezeket a már nem használt erőforrásokat nem szabadítjuk fel, akkor: ✅ A program egyre több memóriát foglal, ami lassuláshoz vagy összeomláshoz vezethet.
✅ Előfordulhat memória-szivárgás, ahol a nem felszabadított memória soha nem kerül vissza az operációs rendszerhez.
✅ A program rosszabb teljesítményt nyújt a feleslegesen foglalt memória miatt.
A szemétgyűjtő (GC) feladata annak felismerése, hogy mely objektumokra nincs már szükség, és ezeknek az automatikus eltávolítása a memóriából. Az alábbi lépésekből áll:
A különböző programozási nyelvek különböző GC algoritmusokat alkalmaznak a memória felszabadítására. Íme a leggyakoribb technikák:
✅ Hatékony, valós időben működik.
✅ Nem okoz hosszú szüneteket a program futása során.
❌ Ciklikus referenciák problémája: ha két objektum egymásra mutat, de más nem hivatkozik rájuk, akkor nem lesznek felszabadítva automatikusan.
Példa Pythonban:
class Node:
def __init__(self):
self.ref = None
a = Node()
b = Node()
a.ref = b
b.ref = a # Ciklikus referencia!
Ebben az esetben a Python szemétgyűjtője speciális módon kezeli a ciklikus referenciákat.
Ez egy kétlépéses GC algoritmus: 1. Megjelölés (Marking):
- A rendszer bejárja az összes még elérhető objektumot és megjelöli őket.
2. Törlés (Sweep):
- Az összes meg nem jelölt objektum törlődik, és a memória felszabadul.
✅ Hatékonyan kezeli a ciklikus referenciákat.
✅ Nem szükséges referencia-számlálókat fenntartani.
❌ A program végrehajtása közben a szemétgyűjtés megállíthatja a programot, ami késleltetéseket okozhat (ún. “stop-the-world” GC).
Java például ezt az algoritmust használja.
Ez egy továbbfejlesztett változata a Mark-and-Sweep algoritmusnak. A különbség az, hogy a megmaradt objektumokat egy helyre tömöríti, hogy a memória fragmentációját csökkentse.
✅ Csökkenti a memóriaszétaprózódást (fragmentációt).
✅ Javítja a memória kihasználtságát.
❌ Még mindig lehet “stop-the-world” szünet, amikor a szemétgyűjtő fut.
A modern szemétgyűjtők “generációkra” osztják az objektumokat: - Fiatal generáció (Young Generation) – az újonnan létrehozott objektumok ide kerülnek.
- Öreg generáció (Old Generation) – azok az objektumok, amelyek hosszabb ideig élnek, átkerülnek ide.
A GC gyakrabban fut a fiatal generációban, mert az objektumok többsége gyorsan elavul.
✅ Gyorsabb, mert nem kell minden objektumot mindig ellenőrizni.
✅ A program teljesítményére kisebb hatással van.
Java és Python ezt a megközelítést használja.
Nyelv | Van beépített GC? | GC Típusa |
---|---|---|
C | ❌ (Nincs) | Manuális memória kezelés (malloc/free )
|
C++ | ❌ (Nincs) | Manuális (new/delete ), vagy smart pointers (unique_ptr , shared_ptr )
|
Java | ✅ (Van) | Mark-and-Sweep, Generational GC |
Python | ✅ (Van) | Referencia számlálás + Generational GC |
C# | ✅ (Van) | Mark-and-Compact, Generational GC |
JavaScript | ✅ (Van) | Mark-and-Sweep |
Bár a GC nagyban megkönnyíti a memória-kezelést, vannak hátrányai is: ❌ Teljesítménycsökkenést okozhat, mert a program futása közben hirtelen belassulhat (ha a GC elindul).
❌ Nem mindig kiszámítható, hogy mikor fog futni.
❌ Nagy memóriahasználatot eredményezhet, mivel a memória felszabadítás nem azonnal történik.