A szemétgyűjtés [ 1] a programozásban az automatikus memóriakezelés egyik formája . Egy speciális folyamat , az úgynevezett szemétgyűjtő , időnként felszabadítja a memóriát azáltal , hogy eltávolítja belőle a feleslegessé vált objektumokat .
Az automatikus szemétgyűjtés javítja a memóriaelérés biztonságát .
A szemétgyűjtést először John McCarthy alkalmazta 1959 -ben egy programozási környezetben az általa fejlesztett funkcionális programozási nyelven, a Lisp -en . Ezt követően más programozási rendszerekben és nyelvekben is használták, főként funkcionális és logikai rendszerekben . Az ilyen típusú nyelveken a szemétgyűjtés szükségessége annak a ténynek köszönhető, hogy az ilyen nyelvek szerkezete rendkívül kényelmetlenné teszi a memóriában lévő objektumok élettartamának nyomon követését és manuális kezelését. Az ezeken a nyelveken széles körben használt listák és az ezeken alapuló összetett adatszerkezetek folyamatosan jönnek létre, bővülnek, bővülnek, másolódnak a programok működése során, és nehéz pontosan meghatározni egy objektum törlésének pillanatát.
Az ipari eljárási és tárgyi nyelvek sokáig nem használták a szemétgyűjtést. Előnyben részesítették a kézi memóriakezelést, mivel hatékonyabb és kiszámíthatóbb. Ám az 1980-as évek második fele óta a szemétgyűjtő technológiát direktív ( imperative ) és objektumprogramozási nyelvekben egyaránt alkalmazzák, a 90-es évek második felétől pedig egyre több, az alkalmazásprogramozásra összpontosító nyelv és környezet létezik. egy gyűjtőmechanizmus szemét vagy az egyetlen, vagy mint az egyik elérhető dinamikus memóriakezelési mechanizmus. Jelenleg Oberon , Java , Python , Ruby , C# , D , F# , Go és más nyelveken használják.
Az irányító nyelvek hagyományos módja a memória kezelésének a kézi. A lényege a következő:
Bármely nyelven, amely lehetővé teszi objektumok létrehozását a dinamikus memóriában, két lehetséges probléma adódhat: lógó hivatkozások és memóriaszivárgás .
A lógó mutató egy olyan objektumra való hivatkozás , amelyet már eltávolítottak a memóriából. Egy objektum törlése után a programban elmentett összes hivatkozás "lógóvá" válik. Az objektum által korábban elfoglalt memória átadható az operációs rendszernek, és elérhetetlenné válik, vagy új objektum lefoglalására használható ugyanabban a programban. Az első esetben egy „lógó” hivatkozás elérésére tett kísérlet elindítja a memóriavédelmi mechanizmust és összeomlik a program, a második esetben pedig beláthatatlan következményekkel jár.
A lógó hivatkozások megjelenése általában egy objektum élettartamának helytelen becslésének eredménye: a programozó meghívja az objektum törlését, mielőtt a használat leállna.
Ha létrehoz egy objektumot a dinamikus memóriában, a programozó nem törölheti azt a használat befejezése után. Ha egy objektumra hivatkozó változóhoz új értéket rendelünk, és nincs más hivatkozás az objektumra, akkor az programozásilag elérhetetlenné válik, de továbbra is lefoglalja a memóriát, mert nem hívták meg a törlési parancsot. Ezt a helyzetet memóriaszivárgásnak nevezik .
Ha a programban folyamatosan jönnek létre olyan objektumok, amelyekre a hivatkozások elvesznek, akkor a memóriaszivárgás a felhasznált memória mennyiségének fokozatos növekedésében nyilvánul meg; ha a program hosszú ideig fut, az általa használt memória mennyisége folyamatosan növekszik, és egy idő után a rendszer észrevehetően lelassul (mivel bármilyen memóriafoglaláshoz swapot kell használni ), vagy a program kimeríti a rendelkezésre álló címteret és hibával végződik.
Ha a számítógép memóriája végtelen lenne, egyszerűen a memóriában hagyhatnánk a felesleges objektumokat. Automatikus memóriakezelés szemétgyűjtéssel – ilyen végtelen számítógép emulációja véges memórián [2] . A szemétgyűjtők korlátai közül sok (nincs garancia arra, hogy a véglegesítő lefut, csak a memóriát kezeli, más erőforrásokat nem) ebből a metaforából fakad.
Szemétgyűjtő rendszeren a programvégrehajtási környezet feladata a memória felszabadítása. A programozó csak dinamikus objektumokat hoz létre és használja, lehet, hogy nem törődik az objektumok törlésével, hiszen a környezet ezt megteszi helyette. Ehhez egy speciális szoftvermodul, az úgynevezett "szemétgyűjtő" szerepel a futtatókörnyezetben. Ez a modul periodikusan fut, meghatározza, hogy a dinamikus memóriában létrehozott objektumok közül melyeket használja már nem, és felszabadítja az általuk elfoglalt memóriát.
A szemétgyűjtő működtetésének gyakoriságát a rendszer jellemzői határozzák meg. A gyűjtő futhat a háttérben, akkor indul, amikor a program inaktív (például amikor a program tétlen, felhasználói bevitelre vár). A szemétgyűjtő feltétel nélkül fut, leállítja a programvégrehajtást ( Stop -the- world ), amikor a következő memóriafoglalási művelet nem hajtható végre, mert az összes rendelkezésre álló memória kimerült. A memória felszabadítása után a megszakított memóriafoglalási művelet folytatódik, és a program végrehajtása folytatódik. Ha kiderül, hogy a memória nem szabadítható fel, a futási környezet "Memória megfogyott" hibaüzenettel leállítja a programot.
Optimális lenne eltávolítani a memóriából azokat az objektumokat, amelyek a program további működése során nem lesznek elérhetők. Az ilyen objektumok azonosítása azonban lehetetlen, mivel ez egy algoritmikusan megoldhatatlan leállítási problémává redukálódik (ehhez elegendő azt feltételezni, hogy valamilyen X objektum akkor és csak akkor kerül felhasználásra, ha a P program sikeresen befejeződik ). Ezért a szemétgyűjtők óvatos becslésekkel biztosítják, hogy egy objektumot a jövőben ne használjanak.
Általában az objektum használatának feltétele a hivatkozások megléte: ha erre az objektumra nincs több hivatkozás a rendszerben, akkor azt nyilvánvalóan a program már nem tudja használni, ezért törölve. Ezt a kritériumot a legtöbb modern szemétgyűjtő alkalmazza, és tárgyelérhetőségnek is nevezik . Elméletileg nem a legjobb, hiszen eszerint az elérhető objektumok közé tartoznak azok az objektumok is, amelyeket soha nem fognak használni, de amelyekre még vannak hivatkozások, de garantálja a védelmet a "lógó" hivatkozások megjelenése ellen, és meglehetősen hatékonyan megvalósítható. .
Informálisan egy elérhető objektum következő rekurzív definíciója adható meg:
Flag Algorithm
Az elérhető objektumok meghatározására szolgáló egyszerű algoritmus, a Mark and Sweep algoritmus a következő:
Ha két vagy több objektum hivatkozik egymásra, de egyik objektum sem hivatkozik kívülről, akkor a teljes csoport elérhetetlennek minősül. Ez az algoritmus lehetővé teszi azoknak az objektumcsoportoknak az eltávolítását, amelyek használata megszűnt, de amelyekben vannak egymásra mutató hivatkozások. Az ilyen csoportokat gyakran „az elszigeteltség szigeteinek” nevezik.
Referencia számláló algoritmusAz elérhetőségi algoritmus másik változata a szokásos referenciaszámlálás . Használata lelassítja a referencia hozzárendelési műveleteket, de az elérhető objektumok meghatározása triviális - ezek mind olyan objektumok, amelyek referenciaszám értéke meghaladja a nullát. További pontosítások nélkül ez az algoritmus az előzőtől eltérően nem távolítja el az elavult objektumok ciklikusan zárt láncait, amelyek egymáshoz kapcsolódnak.
Az elérhetetlen objektumok halmazának meghatározása után a szemétgyűjtő felszabadíthatja az általuk elfoglalt memóriát, és a többit a régiben hagyhatja. Lehetőség van arra is, hogy a memória felszabadítása után a megmaradt objektumok egészét vagy egy részét a memória más területeire helyezzük, ezzel együtt frissítve az összes hivatkozást. Ezt a két megvalósítást nem áthelyezésnek , illetve áthelyezésnek nevezik .
Mindkét stratégiának vannak előnyei és hátrányai is.
Memóriakiosztás és felszabadítási sebesség A nem áthelyezett szemétgyűjtő gyorsabban szabadít fel memóriát (mert csak a megfelelő memóriablokkokat jelöli meg szabadnak), de több időt tölt a lefoglalásával (mivel a memória töredezetté válik, és a lefoglalásnak meg kell találnia a megfelelő mennyiségű megfelelő méretű blokkot a memóriában ). A mozgásgyűjtőnek viszonylag hosszabb ideig tart a szemetet összegyűjteni (extra időbe telik a memória töredezettségmentesítése és az áthelyezett objektumokra vonatkozó összes hivatkozás megváltoztatása), de az áthelyezés rendkívül egyszerű és gyors ( O(1) ) memóriafoglalási algoritmust tesz lehetővé. A töredezettségmentesítés során az objektumokat úgy mozgatják, hogy az összes memóriát két nagy területre osztják fel - foglalt és szabad -, és elmentik a szegélyükre mutató mutatót. Új memória lefoglalásához elegendő ezt a határt elmozdítani, visszaadva egy darabot a szabad memória elejéről. A dinamikus memória objektumaihoz való hozzáférés sebessége Azok az objektumok, amelyek mezői meg vannak osztva, a mozgásgyűjtő segítségével egymáshoz közel helyezhetők a memóriában. Ekkor nagyobb valószínűséggel lesznek a processzor gyorsítótárában egy időben, ami csökkenti a viszonylag lassú RAM -hoz való hozzáférések számát . Külföldi kód kompatibilitás Az áthelyezett szemétgyűjtő problémákat okoz, ha olyan kódot használnak, amelyet nem automatikus memóriakezelés kezel (az ilyen kódot a hagyományos terminológiában idegennek , a Microsoft terminológiájában pedig kezeletlennek nevezik ) . A nem áthelyezhető gyűjtővel rendelkező rendszeren lefoglalt memóriára mutató mutató egyszerűen átadható idegen kódnak, ha legalább egy rendszeres hivatkozást tartunk az objektumra, hogy a gyűjtő ne törölje azt. A mozgó gyűjtő megváltoztatja az objektumok pozícióját a memóriában, szinkronban megváltoztatja az összes hivatkozást, de az idegen kódban nem tudja megváltoztatni a hivatkozásokat, ennek következtében az objektum áthelyezése után az idegen kódra átadott hivatkozások hibásak lesznek. Az idegen kóddal való munkához különféle speciális technikákat használnak, például a rögzítés egy objektum kifejezett blokkolása, amely megtiltja annak mozgását a szemétgyűjtés során.Ahogy a gyakorlat azt mutatja, a nemrég létrehozott objektumok gyakrabban válnak elérhetetlenné, mint a régóta létező tárgyak. Ennek a mintának megfelelően sok modern szemétgyűjtő az összes tárgyat több generációra osztja fel - egy sor objektumra, amelyek élettartama rövid. Amint az egyik generációhoz rendelt memória elfogy, ebben a generációban és minden „fiatalabb” nemzedékben elérhetetlen tárgyak után kutatnak. Mindegyiket eltávolítják, a fennmaradóakat pedig áthelyezik az "idősebb" generációba.
A generációk használata csökkenti a szemétgyűjtési ciklus idejét azáltal, hogy csökkenti a gyűjtés során vizsgált objektumok számát, de ez a módszer futási időt igényel a különböző generációk közötti hivatkozások nyomon követéséhez.
Ahhoz, hogy egy program szemétgyűjtést használjon, számos feltételnek kell teljesülnie, amelyek a nyelvre, a futási környezetre és magára a feladatra vonatkoznak.
Szükség van egy futásidőre egy szemétgyűjtővel Természetesen a szemétszállításhoz dinamikus környezetre van szükség, amely támogatja a program végrehajtását, és egy szemétgyűjtő jelenlétét ebben a környezetben. Az értelmezett nyelvek vagy a virtuális gép bájtkódjára fordított nyelvek esetében a szemétgyűjtő beépíthető a nyelvi vagy bájtkód értelmező kódba, de az objektumkódra fordított nyelvek esetében a szemétgyűjtő kénytelen a rendszer részévé válni. könyvtár, amely végrehajtható fájl létrehozásakor (statikusan vagy dinamikusan) kapcsolódik a programkódhoz, növelve a program méretét és betöltési idejét. Programozási nyelv támogatása A szemétgyűjtő csak akkor tud megfelelően működni, ha pontosan nyomon tudja követni az összes létrehozott objektumra való hivatkozást. Nyilvánvaló, hogy ha a nyelv lehetővé teszi a hivatkozások (mutatók) más adattípusokká (egész számok, bájttömbök stb.) való konvertálását, például C / C++ , akkor lehetetlenné válik az ilyen konvertált hivatkozások használatának nyomon követése, és a szemétgyűjtés értelmetlenné válik. - nem véd a "lelógó" hivatkozásoktól és a memóriaszivárgástól. Ezért a szemétgyűjtés-orientált nyelvek általában jelentősen korlátozzák a mutatóhasználat szabadságát, a címszámítást, a mutatótípusok más adattípusokká való konvertálását. Némelyikük egyáltalán nem rendelkezik „mutató” adattípussal, van, amelyik igen, de nem teszi lehetővé sem a típuskonverziót, sem a módosítást. A programok működésében bekövetkező rövid távú késések technikai megengedhetősége A szemétgyűjtés időszakosan, általában ismeretlen időpontokban történik. Ha a program felfüggesztése a szemétszállítás idejéhez hasonló időre kritikus hibákhoz vezethet , akkor nyilvánvalóan lehetetlen ilyen helyzetben a szemétszállítást használni. Van némi szabad memóriatartalék Minél több memória áll a futási környezet rendelkezésére, annál ritkábban fut a szemétgyűjtő, és annál hatékonyabb. Egy szemétgyűjtő futtatása olyan rendszeren, ahol a szemétgyűjtő rendelkezésére álló memória mennyisége megközelíti a program csúcsigényét, nem hatékony és pazarló. Minél kevesebb memória többlet, annál gyakrabban fut a gyűjtő, és annál több időbe telik a futtatása. A program teljesítményének csökkenése ebben az üzemmódban túl jelentős lehet.A gyakran elmondottakkal ellentétben a szemétgyűjtés jelenléte egyáltalán nem mentesíti a programozót minden memóriakezelési problémától.
Szabadítsa fel az objektum által elfoglalt egyéb erőforrásokat A dinamikus memórián kívül egy objektum más erőforrásokat is birtokolhat, amelyek néha értékesebbek a memóriánál. Ha egy objektum létrehozásakor megnyit egy fájlt, akkor a használat befejeztével be kell zárnia; ha DBMS-hez csatlakozik, meg kell szakítania a kapcsolatot. A kézi memóriakezeléssel rendelkező rendszerekben ez közvetlenül az objektum memóriából való eltávolítása előtt történik, leggyakrabban a megfelelő objektumok destruktoraiban . A szemétgyűjtő rendszerben általában lehetőség van valamilyen kód futtatására közvetlenül az objektum törlése előtt, az úgynevezett véglegesítők , de ezek nem alkalmasak erőforrások felszabadítására, mivel a törlés időpontja nem ismert előre, és előfordulhat, hogy megfordul. az erőforrás sokkal később szabadul fel, mint ahogy az objektum használata megszűnik. Ilyen esetekben a programozónak továbbra is manuálisan kell nyomon követnie az objektum használatát, és manuálisan kell végrehajtania a műveleteket az objektum által elfoglalt erőforrások felszabadításához. A C# -ban van egy kifejezetten erre a célra szolgáló felület IDisposable, a Java - ban AutoCloseable. Memóriaszivárgás A szemétgyűjtő rendszereknél memóriaszivárgás is előfordulhat, bár ezek természete kissé eltérő. A nem használt objektumra való hivatkozás egy másik használt objektumban tárolható, és egyfajta „horgony” lesz, amely a felesleges objektumot a memóriában tartja. Például a létrehozott objektum hozzáadódik a segédműveletekhez használt gyűjteményhez, majd megszűnik a használata, de nem távolítják el a gyűjteményből. A gyűjtemény tartalmazza a hivatkozást, az objektum elérhető marad, és nem gyűjtik a szemetet. Az eredmény ugyanaz a memóriaszivárgás. Az ilyen problémák kiküszöbölésére a futtatókörnyezet támogathat egy speciális szolgáltatást - az úgynevezett gyenge hivatkozásokat . A gyenge hivatkozások nem tartják meg az objektumot, és azzá változnak null, amint az objektum eltűnik - ezért a kódnak fel kell készülnie arra, hogy egy napon a hivatkozás a semmibe fog mutatni. Hatékonyságvesztés a gyakori memóriakiosztással és -felosztással végzett műveleteknél Egyes műveletek, amelyek meglehetősen ártalmatlanok a kézi memóriakezeléssel rendelkező rendszereken, aránytalanul nagy többletköltséget okozhatnak a szemétgyűjtő rendszereknél. Az alábbiakban egy ilyen probléma klasszikus példáját mutatjuk be. String out = "" ; // Feltételezzük, hogy a strings nagyszámú rövid karakterláncot tartalmaz, // amelyekből egy nagy karakterláncot kell összegyűjteni az out változóban. for ( String str : strings ) { out += str ; // Ez a kód minden iterációban // új karakterlánc-változót hoz létre, és memóriát foglal le neki. } Ez a Java-kód úgy néz ki, mintha az egyszer létrehozott out változóhoz a ciklusban minden alkalommal új sor kerülne. Valójában a Java karakterláncai megváltoztathatatlanok, ezért ebben a kódban a ciklus minden egyes lépésében a következő történik:A kézi memóriakezeléshez képest a szemétgyűjtés biztonságosabb, mert megakadályozza a memóriaszivárgást és a lelógó hivatkozásokat az objektumok idő előtti megsemmisítésétől. Ez magát a programozási folyamatot is leegyszerűsíti .
Úgy gondolják, hogy a szemétgyűjtés jelentősen csökkenti a memóriakezelési többletköltséget azokhoz a nyelvekhez képest, amelyek ezt nem alkalmazzák. Egy tanulmány [3] szerint a C programozók teljes fejlesztési idejük 30-40%-át (a hibakeresést nem számítva) kizárólag memóriakezelésre fordítják. Vannak azonban ellentétes következtetésű tanulmányok, például a [4]-ben azt állítják, hogy a valódi különbség a szoftverfejlesztés sebességében a C ++-ban, ahol nincs automatikus szemétgyűjtés, és a Java-ban, ahol ez megvalósul. , kicsi.
A szemétgyűjtő jelenléte egy tapasztalatlan fejlesztőben azt a téves hiedelmet keltheti, hogy egyáltalán nem kell figyelnie a memóriakezelésre. Noha a szemétgyűjtő csökkenti a helytelen memóriakezelési problémákat, nem szünteti meg őket teljesen, és a továbbra is fennálló hibák nem nyilvánvaló hibákként, például általános védelmi hibaként jelennek meg , hanem elvesztegetett memóriaként, amikor egy program fut. Tipikus példa: ha a programozó szem elől tévesztette, hogy legalább egy nem nullázható mutató maradt az objektumon a globális hatókörben, akkor az ilyen objektum soha nem törlődik; ilyen pszeudo-szivárgást nagyon nehéz megtalálni.
Gyakran nem csak az erőforrás felszabadítása fontos, hanem annak biztosítása is, hogy felszabaduljon valamilyen más eljárás meghívása előtt – például fájlok megnyitása, bejegyzések a kritikus szakaszokban. Ha megpróbáljuk ezeket az erőforrásokat a szemétgyűjtőnek átadni (a véglegesítők segítségével ), az nem lesz hatékony, sőt helytelen, ezért manuálisan kell kezelnie őket. A közelmúltban még a szemétgyűjtővel rendelkező nyelveken is bevezettek egy szintaxist, amely garantálja a "cleanup code" (például egy speciális "destruktor" módszer) végrehajtását, ha egy objektumra hivatkozó változó kikerül a hatókörből.
Sok esetben a szemétgyűjtő rendszerek kevésbé hatékonyak, mind a sebesség, mind a memóriahasználat tekintetében (ami elkerülhetetlen, hiszen maga a szemétgyűjtő is fogyaszt erőforrásokat, és a megfelelő működéshez több szabad memóriára van szüksége). Ezenkívül a szemétgyűjtő rendszerben nehezebb olyan alacsony szintű algoritmusokat megvalósítani, amelyek közvetlen hozzáférést igényelnek a számítógép RAM-jához, mivel a mutatók szabad használata lehetetlen, és a közvetlen memóriaelérés speciális, alacsony szintű nyelveken írt interfészeket igényel. . Másrészt a modern szemétgyűjtő rendszerek nagyon hatékony memóriakezelési algoritmusokat használnak minimális többletköltséggel. Azt a tényt sem lehet figyelmen kívül hagyni, hogy a RAM viszonylag olcsó és elérhető. Ilyen körülmények között rendkívül ritkák az olyan helyzetek, amikor a szemétszállítás költségei válnak kritikussá a program hatékonysága szempontjából.
A szemétgyűjtés jelentős előnye, hogy a dinamikusan létrehozott objektumok hosszú ideig élnek, sokszor duplikálódnak, és a rájuk való hivatkozások átkerülnek a program különböző részei között. Ilyen körülmények között meglehetősen nehéz meghatározni azt a helyet, ahol az objektum már nem használható, és törölhető. Mivel éppen ez a helyzet a dinamikusan változó adatstruktúrák (listák, fák, grafikonok) széles körben elterjedt használatával, a szemétgyűjtésre olyan funkcionális és logikai nyelveken van szükség, amelyek széles körben használnak ilyen struktúrákat, mint például a Haskell , Lisp vagy Prolog . A szemétgyűjtés hagyományos imperatív nyelveken való használatát (strukturális paradigmán alapulva, esetleg objektumlétesítményekkel kiegészítve) a programfejlesztés egyszerűsége és gyorsasága, valamint a végrehajtás hatékonysága közötti kívánt egyensúly határozza meg.
Egyes kötelező nyelvek támogatása a destruktor automatikus meghívásához, ha egy objektum kikerül a szintaktikai hatókörből ( C++ [5] , Ada , Delphi ) lehetővé teszi, hogy a memóriafelszabadító kódot a destruktorba helyezze, és biztos lehet benne, hogy mindenképpen meghívásra kerül. . Ez lehetővé teszi a veszélyes helyek koncentrálását az osztály megvalósításán belül, és nem igényel többletforrást, bár magasabb követelményeket támaszt a programozói képesítéssel szemben. Ugyanakkor lehetővé válik az objektum által elfoglalt egyéb erőforrások biztonságos felszabadítása a destruktorban.
A szemétgyűjtés alternatívája az " okos hivatkozások " technológiája, amikor egy dinamikus objektumra való hivatkozás maga is nyomon követi a felhasználók számát, és automatikusan törli az objektumot, ha ez a szám nullává válik. Az "okos hivatkozásokkal" jól ismert probléma, hogy olyan körülmények között, amikor a program folyamatosan sok kis, rövid élettartamú objektumot hoz létre a memóriában (például listastruktúrák feldolgozása során), teljesítményükben veszítenek a szemétgyűjtésből.
Az 1960-as évek óta létezik régióalapú memóriakezelés , egy olyan technológia, amelyben a memóriát viszonylag nagy, régióknak nevezett töredékekre osztják , és már a régiókon belül a memóriát az egyes objektumokhoz rendelik. Kézi vezérlés esetén a régiókat maga a programozó hozza létre és törölje, az automatikus vezérlésnél pedig különféle típusú konzervatív becslések segítségével állapítják meg, hogy a régión belül lefoglalt összes objektum mikor szűnik meg a használat, ezt követően a memóriakezelő rendszer törli a teljes régiót. Például létrejön egy régió, amelyben a memória le van foglalva az összes objektumhoz, amelyet egy bizonyos hatókörön belül hoztak létre, nem kerül kimenni, és ez a régió egyetlen paranccsal megsemmisül, amikor a program végrehajtása kilép ebből a hatókörből. A memóriakezelésben (akár kézi, akár automatikus) az egyes objektumokról a nagyobb egységekre való átállás sok esetben lehetővé teszi, hogy leegyszerűsítsük az objektumok élettartamának elszámolását, és egyúttal csökkentsük a rezsiköltségeket. A regionális memóriakezelés megvalósítása (különböző fokú automatizálással) számos programozási nyelvhez létezik, köztük az ML , Prolog , C , Cyclone .
A Rust programozási nyelv a "tulajdonjog" fogalmát kínálja, amely a fordító szigorú ellenőrzésén alapul az objektumok élettartama és hatóköre felett. Az ötlet az, hogy amikor egy objektumot létrehoznak, a hozzá hivatkozáshoz rendelt változó lesz az objektum "tulajdonosa", és a tulajdonos változó hatóköre korlátozza az objektum élettartamát. A tulajdonos hatóköréből való kilépéskor az objektum automatikusan törlődik. Ha egy objektumhivatkozást egy másik változóhoz rendelünk, az „kölcsönözhető”, de a kölcsönzés mindig ideiglenes, és az objektum tulajdonosának élettartamán belül be kell fejeződnie. A "tulajdonjog" átruházható egy másik változóra (például létrejöhet egy objektum egy függvényen belül, és ennek eredményeként visszaadható), de az eredeti tulajdonos elveszíti hozzáférését az objektumhoz. Összességében a szabályok célja, hogy biztosítsák, hogy egy objektumot ne lehessen ellenőrizetlenül módosítani idegen hivatkozások révén. A fordító statikusan követi az objektumok élettartamát: minden olyan művelet, amely akár az objektumra való hivatkozás mentéséhez is vezethet, miután a tulajdonosa kikerült a hatókörből, fordítási hibához vezet, ami kiküszöböli a "lógó hivatkozások" megjelenését és a memóriaszivárgást. Ez a megközelítés bonyolítja a programozási technikát (illetve megnehezíti a nyelv elsajátítását), de kiküszöböli mind a kézi memóriafoglalást és -felszabadítást, sem a szemétgyűjtést.
A szemétgyűjtést mint a programvégrehajtási környezet nélkülözhetetlen attribútumait olyan deklaratív paradigmán alapuló nyelvekben használják , mint a LISP , ML , Prolog , Haskell . Ennek szükségessége ebben az esetben e nyelvek természetéből fakad, amelyek nem tartalmaznak eszközöket az objektumok élettartamának manuális kezelésére, és nincs lehetőségük az ilyen eszközök természetes integrációjára. Az alapvető összetett adatstruktúra az ilyen nyelvekben általában egy dinamikus, egyedileg összekapcsolt lista, amely dinamikusan lefoglalt listacellákból áll. A listákat folyamatosan készítik, másolják, duplikálják, kombinálják és felosztják, ami szinte lehetetlenné teszi az egyes lefoglalt listacellák élettartamának manuális kezelését.
A kötelező nyelveken a szemétgyűjtés az egyik lehetőség, a kézi és néhány alternatív memóriakezelési technika mellett. Itt a programozás egyszerűsítésének és a hibák megelőzésének eszközeként tekintenek rá . Az egyik első összeállított kötelező nyelv a szemétgyűjtéssel az Oberon volt , amely bemutatta ennek a mechanizmusnak az alkalmazhatóságát és meglehetősen magas hatékonyságát az ilyen típusú nyelvekre, de a Java nyelv széles népszerűséget és népszerűséget hozott ennek a megközelítésnek . Ezt követően a Java megközelítés megismétlődött a .NET környezetben és szinte az összes azon működő nyelven, kezdve a C # -től és a Visual Basic .NET -től . Ugyanakkor számos értelmezett nyelv jelent meg (JavaScript, Python, Ruby, Lua), ahol a szemétgyűjtés is szerepelt a nem programozók nyelvi elérhetősége és a kódolás egyszerűsítése érdekében. A hardveres teljesítmény növekedése, amely a gyűjtők fejlesztésével egyidejűleg történt, oda vezetett, hogy a szemétszállítás többletköltsége megszűnt. A legtöbb modern szemétgyűjtő kötelező nyelvnek egyáltalán nincs módja az objektumok (például a törlés operátor) kifejezetten manuális törlésére. Az értelmezőt használó vagy bájtkódra fordító rendszerekben a szemétgyűjtő a futási idő része; ugyanazokon a nyelveken, amelyek a processzor objektumkódjára fordítanak, kötelező rendszerkönyvtárként valósul meg.
Van még néhány nyelv ( nim , Modula-3 , D ), amely támogatja a kézi és az automatikus memóriakezelést is, amelyekhez az alkalmazás két külön kupacot használ.