Válasz
A szemétgyűjtéshez adatstruktúrákra van szükség az allokációk követése és / vagy a referenciaszámlálás. Ezek a memóriában, a teljesítményben és a nyelv bonyolultságában megteremtik az általános költségeket. A C ++ úgy lett megtervezve, hogy “közel legyen a fémhez”, más szóval, a kompromisszum és a kényelmi funkciók magasabb teljesítményű oldalát veszi igénybe. Más nyelvek másként teszik ezt a kompromisszumot. Ez a nyelvválasztás egyik szempontja, amelyet Ön jobban hangsúlyoz.
Ennek ellenére a C ++ nyelven rengeteg referenciaszámlálási séma létezik, amelyek meglehetősen könnyűek és teljesítőek, de a könyvtárakban találhatók, mind kereskedelmi, mind pedig nyílt forráskódúak, nem pedig maga a nyelv része. Az objektum élettartamának kezeléséhez szükséges referenciaszámlálás nem azonos a szemétszállítással, de sok azonos típusú problémát megold, és jobban illeszkedik a C ++ alapvető megközelítéséhez.
Megjegyzések
- Másodlagos probléma, hogy a GC nem determinisztikus. Az objektum lehet, vagy még mindig nincs a memóriában még jóval azután, hogy a program " leesett " it. Az újraszámlálás életciklusai meghatározóak, amikor az utolsó referencia eldobásakor a memória eldobódik. Ez nemcsak a memória hatékonyságára, hanem a hibakeresésre is vonatkozik. Gyakori programozási hiba a " zombi " objektum, az elméletileg leesett referencia memória. A GC sokkal inkább elfedi ezt a hatást, és olyan hibákat hoz létre, amelyek szakaszosak és rendkívül nehezen nyomon követhetők.
- – a modern gc ' nem követi nyomon a kiosztásokat és nem számolja a referenciákat. jelenleg a veremben van, és csak sűrít és töröl minden mást (egyszerűsítve), és a GC általában csökkentett nyelvi bonyolultságot eredményez. Még a teljesítmény előnye is megkérdőjelezhető.
- Ööö, @kylben, az automatikus GC nyelvbe sütésének lényege, hogy lehetetlenné válik a zombi objektumok hivatkozása, mert a GC csak olyan tárgyakat szabadít fel, amelyekre lehetetlen hivatkozni! Olyan nehezen nyomon követhető hibákat kap, amelyekről ' beszél, amikor manuális memóriakezeléssel hibázik.
- -1, a GC nem számít hivatkozások. Ráadásul a memóriahasználattól és a kiosztási sémától függően a GC gyorsabb lehet (a memóriahasználat általános költségével). Tehát a teljesítményről szóló érv is tévedés. Valójában csak a fémhez közeli pont érvényes.
- Sem a Java, sem a C # nem használ referenciaszámlálást: a referenciaszámláláson alapuló GC-sémák ehhez képest meglehetősen primitívek és sokkal rosszabbul teljesítenek, mint a modern szemétgyűjtők (főleg azért, mert memóriaírást kell végezni a referenciaszám megváltoztatásához, amikor referenciát másol!)
Válasz
Szigorúan véve, a C nyelvben egyáltalán nincs memóriakezelés. A malloc () és a free () nem kulcsszavak a nyelvben, hanem csak függvények, amelyeket egy könyvtárból hívnak meg.Ez a megkülönböztetés most pedáns lehet, mert a malloc () és a free () a C szabványos könyvtár részét képezik, és a C bármely szabványnak megfelelő megvalósítása biztosítja, de ez a múltban nem volt mindig igaz.
Miért szeretne olyan nyelvet, amelynek nincs szabványa a memóriakezeléshez? Ez C eredetére “hordozható összeállításként” vezet vissza. Számos olyan hardver és algoritmus létezik, amelyek hasznosak lehetnek, vagy akár megkövetelik a speciális memóriakezelési technikákat. Ha jól tudom, nincs mód a Java natív memóriakezelésének teljes letiltására és helyettesítésére a sajátjával. Ez egyszerűen nem elfogadható néhány nagy teljesítményű / minimális erőforrás esetén. A C szinte teljes rugalmasságot biztosít az infrastruktúra kiválasztásához. a programod használni fogja. A fizetett ár az, hogy a C nyelv nagyon kevés segítséget nyújt a helyes, hibamentes kódíráshoz.
Megjegyzések
- +1 egyet a jó válaszért, de különösen a " esetében is. A fizetett ár az, hogy a C nyelv nagyon kevés segítséget nyújt a helyes, hibamentes kód megírásához "
- A C rendelkezik memóriakezeléssel – de ez csak működik, így az emberek alig veszik észre. Van ' statikus memória, regiszterek és a verem. Amíg el nem kezdi a kiosztást a kupacból, ' rendben van és finom. Ez ' s azt a kupacallokációt, amely elrontja a dolgokat As Java esetén mindenki megírhatja saját Java futási idejét – ' rengeteg közül lehet választani, beleértve azt is, amit " rendszernek ' s Java ". A .NET nagyjából mindent megtehet, amit a C képes – csak a C ++ ' natív képességeitől marad el (pl. Az osztályokat csak .NET-ben kezelik). Természetesen Önnek is van C ++. NET-je, amelyben minden megtalálható, amit a C ++, és minden .NET-t.
- @Luaan ' d azt mondom, hogy ' nagyon nagyvonalú meghatározása annak, hogy " memóriakezelést " " Amíg el nem kezdesz kiosztani a kupacból, ' jól vagy finom. ' ez a halom kiosztás, amely elrontja a dolgokat ", ez ' tetszik mondani egy autó tökéletesen jó repülőgép, csak ' nem képes repülni.
- @ CharlesE.Grant Nos, egy tisztán funkcionális nyelv ezzel mindent megtehet fajta memóriakezelés. Csak azért, mert a halomallokáció jó kompromisszumot jelent egyes felhasználási esetekben, nem jelenti azt, hogy ' nem azt jelenti, hogy ez ' az összes nyelv / futásidejének referenciaértéke . ' nem tetszik, hogy a memóriakezelés leáll " memóriakezeléssel " csak azért, mert ' s egyszerű, egyenes, a kulisszák mögé rejtve. A statikus memóriaallokáció megtervezése továbbra is memóriakezelés, csakúgy, mint a verem és bármi más rendelkezésre álló felhasználása.
- " bármilyen szabványnak megfelelő megvalósítás " nem igaz, csak a szabványnak megfelelő gazdagép-környezet megvalósításához. Néhány platform / standard könyvtár, a legtöbb 8 vagy 16 bites beágyazott mikrovezérlőhöz, nem ad meg
malloc()
vagyfree()
. (például az MLAP-fordítók a PIC-hez)
Válasz
Az igazi válasz az, hogy biztonságos, hatékony szemétszedési mechanizmus az nyelvszintű támogatás az átlátszatlan hivatkozásokhoz. (Vagy fordítva: a közvetlen memóriamanipuláció nyelvszintű támogatásának hiánya .)
A Java és a C # meg tudja csinálni, mert vannak olyan speciális hivatkozási típusaik, amelyek nem kezelhetők. Ez a futásidejének szabadságát teszi olyan dolgok végrehajtására, mint a memóriában lefoglalt objektumok áthelyezése , ami elengedhetetlen a nagy teljesítményű GC megvalósításhoz .
A nyilvántartáshoz: egyetlen modern GC megvalósítás sem használ referenciaszámlálást , tehát ez teljesen piros hering. A modern GC-k generációs gyűjtést használnak, ahol az új allokációkat lényegében ugyanúgy kezelik, mint a veremallokációkat egy olyan nyelven, mint a C ++, majd az újonnan kiosztott, még életben lévő objektumokat periodikusan külön “túlélő” helyre és egy teljes generációra helyezik át. tárgyakat egyszerre osztják le.
Ennek a megközelítésnek vannak előnyei és hátrányai: a fejlõdés az, hogy a GC-t támogató nyelvû halomallokációk ugyanolyan gyorsak, mint a veremallokációk egy olyan nyelven, amely nem támogatja a GC-t, és hátránya, hogy azok az objektumok, amelyek megtisztítását el kell végezni a megsemmisítés előtt, külön mechanizmust igényelnek (pl. C #” s using
kulcsszó), különben a tisztító kódjuk nem determinisztikusan fut.
Ne feledje, hogy a nagy teljesítményű GC egyik kulcsa, hogy a referenciák speciális osztályának nyelvi támogatással kell rendelkeznie. A C-nek nincs ilyen nyelvi támogatása, és soha nem is lesz; mivel a C ++ operátora túlterhelt, emulálhat egy GC “d” típusú típust, bár ezt gondosan kellene elvégezni. Valójában, amikor a Microsoft feltalálta a CL + (.NET futásidejű) alatt futó C ++ dialektusukat, új szintaxist kellett kitalálniuk a “C # stílusú hivatkozásokhoz” (pl. Foo^
) megkülönböztetni őket a “C ++ – stílus referenciáktól” (pl. Foo&
).
Amit a C ++ tartalmaz, és amit a C ++ programozói rendszeresen használnak, az intelligens mutatók , amelyek valójában csak referenciaszámláló mechanizmusok. Nem tartanám a referenciaszámlálást “igaz” GC-nek, de sok ugyanolyan előnyt nyújt, lassabb teljesítmény árán, mint akár a kézi memóriakezelés, akár a valódi GC, de a determinisztikus rombolás előnyével.
A nap végén a válasz valóban egy nyelvtervezésre vezethető vissza: C választott, a C ++ választott, amely lehetővé tette, hogy visszafelé kompatibilis legyen a C-vel, miközben továbbra is elég jó alternatívákat kínál a legtöbb célra, és a Java és a C # más választást hajtott végre, amely nem kompatibilis a C-vel, de a legtöbb célra is elég jó. Sajnos nincs ezüst golyó, de ha ismeri a különféle választásokat, az segít kiválasztani a megfelelőt bármely olyan programhoz, amelyet éppen építeni próbál.
Megjegyzések
- Ez a kérdésre adott tényleges válasz
- a c ++ részt, manapság meg kell nézni az std :: unique_ptr és std :: move 🙂
- nincs modern GC implem Az entation referenciaszámlálást használ : a cPython mind az referenciaszámlálást, mind az automatikus gyűjtést használja.
- @ Mike76: A kiosztási oldalon a GC-allokátor ugyanolyan gyorsan fog dolgozni, mint a verem-allokáció, és a GC egyszerre több ezer objektumot képes lefoglalni. Nem számít, hogy mit csinálsz egy újraszámlálás megvalósításával, az allokáció és az elosztás soha nem lesz gyorsabb, mint
malloc
ésfree
. Tehát igen, a GC lényegesen gyorsabb lehet. (Ne feledje, hogy azt mondtam, hogy " " lehet – természetesen az egyes programok pontos teljesítményét sok tényező befolyásolja.) - egyetlen modern GC megvalósítás sem használ referenciaszámlálást a Swift automatikus referenciaszámlálást használ.
Válasz
Mivel a C ++ erejének használatakor nincs szükség.
Gyógynövény Sutter:” Évek óta nem írtam törlést. ”
lásd Modern C ++ kód írása: hogyan alakult a C ++ az évek során 21:10
Sokakat meglephet tapasztalt C ++ programozók.
Megjegyzések
- Érdekes. Mai olvasmányom.
- Bah, videó. De még kevésbé érdekes.
- érdekes videó. 21 perc és 55 perc volt a legjobb bit. Kár, hogy a WinRT hívások továbbra is C ++ / CLI bumpf-nek tűntek.
- @ dan04: Ez ' igaz. De ha C-ben írsz, megkapod, amit kértél.
- Az intelligens mutatók kezelése nem igényesebb, mint annak biztosítása, hogy ne ' t felesleges hivatkozásokkal rendelkezzenek egy szemétszedett környezetben. Mivel a GC ' nem tudja olvasni a gondolatait, ezért ' sem varázslat.
Válasz
A “szemétgyűjtő” minden olyan folyamat, amely rendszeresen fut, hogy ellenőrizze, vannak-e hivatkozatlan objektumok a memóriában, és vannak-e törlések. (Igen, tudom, hogy ez durva túlegyszerűsítés). Ez nem a nyelv, hanem a keretrendszer tulajdonsága.
Vannak szemétgyűjtők, amelyek a C és a C ++ -hoz vannak írva – például ez .
Az egyik oka annak, hogy egy szót nem “adtak hozzá” a nyelvhez, annak a meglévő kódnak a hatalmas mennyisége lehet, amely soha nem használná, mivel saját kódot használnak a memória kezelésére. a C és C ++ nyelven írt alkalmazások típusainak nincs szükségük a szemétszedési folyamathoz kapcsolódó költségekre.
Megjegyzések
- De a jövőbeni programok írva elkezdte használni a szemétszedőt, nem?
- Noha a szemétszállítás elméletileg független minden programozási nyelvtől, elég nehéz hasznos GC-t írni a C / C ++ -hoz, sőt lehetetlen bolondbiztosat készíteni (legalább annyira bolondbiztos, mint a Java ' s) – a Java oka annak, hogy ellenőrzött virtualizált környezetben fut. Ezzel szemben a Java nyelvet a GC-hez tervezték, és ' nehezen fog írni egy Java fordítót, amely nem ' nem teszi meg a GC-t .
- @tdammers: Egyetértek azzal, hogy a szemétszedést a nyelvnek támogatnia kell. A lényeg azonban nem a virtualizáció és az ellenőrzött környezet, hanem a szigorú gépelés. A C és a C ++ típusa gyengén van beírva, így lehetővé teszik például a mutató egész változóban történő tárolását, a mutatók eltolásokból történő rekonstruálását és olyan dolgokat, amelyek megakadályozzák, hogy a gyűjtő megbízhatóan meg tudja mondani, hogy mi érhető el (a C ++ 11 tiltja a későbbieket, hogy legalább konzervatív gyűjtők). A Java-ban mindig tudja, mi a hivatkozás, így pontosan összegyűjtheti, még akkor is, ha natívra van állítva.
- @Thorbj ø rnRavnAndersen: Írhatok egy érvényes C program, amely úgy tárolja a mutatókat, hogy soha egyetlen szemétszedő sem találná meg őket. Ha ezután egy szemétgyűjtőt felcsatol a
malloc
ésfree
oldalra, akkor megtörné a helyes programomat. - @Thorbj ø rnRavnAndersen: Nem, addig nem hívnám '
free
, amíg végeztem vele . De a javasolt szemétgyűjtő, amely nem ' nem szabadítja fel a memóriát, amíg nem nevezem ki kifejezetten azfree
is ' ta szemétgyűjtő egyáltalán.
Válasz
A C-t egy olyan korszakban tervezték, amikor a szemétszállítás alig volt egy opció. Olyan felhasználásokra is szánták, ahol a szemétszállítás általában nem fog működni – csupasz fém, valós idejű környezet, minimális memória és minimális futásidejű támogatás. Ne feledje, hogy a C volt az első unix megvalósítási nyelve, amely 64 * K * bájt memóriával rendelkező pdp-11-en futott. A C ++ eredetileg a C kiterjesztése volt – a választás már megtörtént, és nagyon nehéz egy szemétgyűjtést oltani egy meglévő nyelvre. Olyan dolog, amelyet a földszintről kell beépíteni.
Válasz
Nincsenek pontos árajánlataim, de Bjarne és Herb Sutter is mond valamit:
A C ++ – nak nincs szüksége szemétszedőre, mert nincs szemétje.
Modern C ++ intelligens mutatókat használ, és ezért nincs szemétje.
Megjegyzések
- mi az intelligens mutató?
- ha ez volt az egyszerű, senki sem valósított volna meg egyetlen GC-t sem.
- @deadalnix: Helyes, mert soha senki nem hajt végre túl bonyolultat, lassan, dagadtan vagy fölöslegesen. Minden szoftver 100% -ban hatékony, igaz?
- @deadalnix – A memóriakezelés C ++ megközelítése újszerűbb, mint a szemétgyűjtők. A RAII-t Bjarne Stroustrup találta fel a C ++ számára. A romboló tisztítás régebbi ötlet, de a kivétel-biztonság biztosításának kulcsfontosságú szabályai. Nem tudom ', hogy pontosan mikor írták le magát az ötletet, de az első C ++ szabványt 1998-ban véglegesítették, és a Stroustrups " Design és a C ++ evolúciója " 1994-ig nem jelent meg ' t, a kivételek pedig a C ++ viszonylag friss kiegészítései voltak – a " Annotated C ++ Reference Manual " 1990-ben, azt hiszem. A GC-t 1959-ben találták ki a Lisp-hez.
- @deadalnix – tudod, hogy legalább egy Java virtuális gép referenciaszámláló GC-t használt, amelyet intelligens mutatóosztály használatával (majdnem) C ++ stílusú RAII használatával lehetett megvalósítani – pontosan azért, mert hatékonyabb volt a többszálas kódoknál, mint a meglévő virtuális gépek? Lásd: www.research.ibm.com/people/d/dfb/papers/Bacon01Concurrent.pdf. Az egyik ok, amiért nem látja ezt a gyakorlatban a C ++ – ban, az a szokásos GC gyűjtemény – összegyűjthet ciklusokat, de ' nem választhat biztonságos destruktorrendelés ciklusok jelenlétében, és így nem tudja biztosítani a megbízható rombolótisztítást.
Válasz
Ön kérdezd meg, miért nem frissítették ezeket a nyelveket egy opcionális szemétgyűjtővel.
Az opcionális szemétszállítás problémája, hogy nem keverheted össze a különböző modelleket használó kódokat. Vagyis, ha olyan kódot írok, amely feltételezi, hogy szemétgyűjtőt használ, akkor nem tudja használni a programjában, amelynek kikapcsolva van a szemétszállítás. Ha mégis, akkor mindenhol kiszivárog.
Válasz
Különböző problémák vannak, többek között …
- Bár a GC-t a C ++ és esetleg C előtt találták ki, mind a C, mind a C ++ bevezetése megtörtént, mielőtt a GC-ket széles körben elfogadták volna praktikusnak.
- Nem lehet egyszerűen megvalósítani GC nyelv és platform mögöttes, nem GC nyelv nélkül.
- Bár a GC bizonyíthatóan hatékonyabb, mint a nem GC, a tipikus ütemtervekben kifejlesztett tipikus alkalmazáskódokhoz stb., Vannak olyan kérdések, ahol a nagyobb fejlesztési erőfeszítések jó kereskedelmet jelentenek Az off-off és a speciális memóriakezelés felülmúlja az általános célú GC-t. Ezenkívül a C ++ általában minden további fejlesztési erőfeszítés nélkül is bizonyíthatóan hatékonyabb, mint a legtöbb GC-nyelv.
- A GC nem általánosan biztonságosabb, mint a C ++ – stílusú RAII . A RAII lehetővé teszi a memórián kívüli erőforrások automatikus tisztítását, alapvetően azért, mert megbízható és időszerű destruktorokat támogat. Ezeket a hagyományos GC módszerekkel nem lehet kombinálni a referencia ciklusokkal kapcsolatos problémák miatt.
- A GC nyelveknek megvannak a maguk jellemzői fajta memória szivárgás, különös tekintettel a memóriára, amelyet soha többé nem fognak használni, de léteztek olyan hivatkozások, amelyeket soha sem semmisítettek meg vagy nem írtak felül. Ennek kifejezett megkövetelése elvben nem különbözik a
delete
vagyfree
kifejezett igényétől. A GC megközelítésnek még mindig van előnye – nincsenek lógó referenciák -, és a statikus elemzés néhány esetet megfoghat, de megint nincs minden esetre tökéletes megoldás.
Alapvetően részben ” s a nyelvek koráról, de amúgy is mindig lesz helye a nem GC nyelveknek – még akkor is, ha ez egy kicsit hiánypótló hely. És komolyan, a C ++ – ban a GC hiánya nem jelent nagy problémát – a memóriád másképp van kezelve, de nem kezeletlen.
A C ++ által kezelt mikroszolgáltatások legalább képesek keverni a GC-t és a nem A GC ugyanabban az alkalmazásban, lehetővé téve az egyes előnyök keverését és egyeztetését, de nincs tapasztalatom, hogy megmondjam, mennyire működik ez a gyakorlatban.
Ismétlődő linkek a kapcsolódó válaszokra az enyémek …
- https://stackoverflow.com/questions/1529679/how-do-you-program-safely-outside-of-a-managed-code-environment/1529731#1529731
- https://stackoverflow.com/questions/1424660/garbage-collection-vs-non-garbage-collection-programming-languages/1496547#1496547
- https://stackoverflow.com/questions/4984849/why-circular-referenced-objects-with-del-defined-are-uncollectable-in-python/4984934#4984934
- https://stackoverflow.com/questions/5009869/how-to-implement-garbage-collection-in-c/5009984#5009984
Válasz
El tudja képzelni, hogy írjon egy eszközkezelőt egy hulladékgyűjtéses nyelvre? Hány bit jöhet le sor, miközben a GC futott?
Vagy operációs rendszer? Hogyan indíthatná el a szemétszállítás futását, mielőtt még a kernelt is elindítaná?
Megjegyzések
- C jó magas szintre? Kihintettem az italomat az egész billentyűzetemen.
- Nos, sok magasabb szintű feladatot mondott " ". Lehet trollszámláló (egy, kettő, sok …). És valójában nem mondta ' azt, ami magasabb. A vicceket leszámítva azonban ' igaz – bizonyíték arra, hogy számos jelentős, magasabb szintű projektet sikeresen kidolgoztak C-ben. Jobb választási lehetőségek is lehetnek most sok ilyen projekt esetében, de egy működő projekt erősebb bizonyíték, mint a spekuláció arról, hogy mi lehetett.
- Vannak ' néhány kezelt operációs rendszer, és elég jól működnek. Valójában, amikor az egész rendszert kezeli, a felügyelt kód használatának teljesítménye még alacsonyabbra csökken, akár gyorsabb lehet, mint a kezeletlen kód a valós élethelyzetekben. Természetesen ezek mind " kutató OS " – ott ' s nagyjából nem módja annak, hogy kompatibilisek legyenek a meglévő nem felügyelt kódokkal, a teljesen virtualizált, nem felügyelt operációs rendszer létrehozása mellett a kezelt operációs rendszeren belül. A Microsoft egy bizonyos ponton mégis javasolta, hogy a Windows Server helyére léphet egy ilyen, bár egyre több szerverkódot írnak a .NET-re.
Válasz
A rövid és unalmas válasz erre a kérdésre az, hogy a szemétszedőket írók számára létezik egy nem szeméttől összegyűjtött nyelv. Fogalmilag nem könnyű olyan nyelvvel rendelkezni, amely egyúttal nagyon pontos vezérlést tesz lehetővé a memória elrendezése felett és a tetején fut egy GC.
A másik kérdés: miért nem rendelkeznek C és C ++ szemétszedők.Nos, tudom, hogy a C ++ -on van páran, de nem igazán népszerűek, mert kénytelenek olyan nyelvvel foglalkozni, amelyet elsősorban nem GC-szerkesztésre terveztek, és azokkal az emberekkel, akik még mindig használják a C ++ -t ez a kor valójában nem az a fajta, amelyik hiányol egy GC-t.
A GC hozzáadása helyett egy régi, nem GC-nyelvű nyelvhez valójában könnyebb létrehozni egy új nyelvet, amely rendelkezik a legtöbb ugyanaz a szintaxis, miközben támogat egy GC-t. Erre jó példa a Java és a C #.
Megjegyzések
- Valahol a programmers.se vagy SO-n ott ' azt állítja, hogy valaki azt állította nekem, hogy valaki egy önindítással rendelkező szeméttel összegyűjtött dolgon dolgozik – az IIRC alapvetően a virtuális gépet egy GC nyelv használatával valósítja meg, egy bootstrapping részhalmazzal, amelyet maga a GC valósít meg . Elfelejtem a nevet. Amikor utánanéztem, kiderült, hogy ' d alapvetően soha nem érték el az ugrást a GC nélküli részhalmazról a működő GC szintre. értéke elvileg lehetséges, de az AFAIK ezt a gyakorlatban még soha nem sikerült megvalósítani – ez ' minden bizonnyal a nehéz dolgok elvégzésének esete.
- @ Steve314: I ' Szeretném látni, hogy ha valaha is emlékszel, hol találtad!
- megtaláltad! Lásd a stackoverflow.com/questions/3317329/… megjegyzéseit, amelyek a Klein virtuális gépre vonatkoznak. A probléma egy része – a kérdés lezárult.
- BTW – Úgy tűnik, nem tudom a @missingno-val kezdeni a megjegyzéseimet – mit ad?
- @ steve314: Miután megírtam ezt a választ szál csatolva van, már kapok értesítést az összes megjegyzésről. A @ -poszt végrehajtása ebben az esetben felesleges lenne, és az SE nem engedélyezi (ne ' ne kérdezzen tőlem miért ). (A valódi ok azért van, mert hiányzik a számom)
Válasz
A szemétszállítás alapvetően nem kompatibilis egy a DMA-képes hardver illesztőprogramjainak fejlesztéséhez használt rendszernyelv.
Teljesen lehetséges, hogy az objektum egyetlen mutatója valamilyen periféria hardverregiszterében lesz tárolva. Mivel a szemétszedő nem tudná erről azt gondolná, hogy az objektum elérhetetlen, és összegyűjti.
Ez az argumentum duplán igaz a GC tömörítéséhez. Még akkor is, ha vigyázna a memóriában a hardveres perifériák által használt objektumokra történő hivatkozások fenntartására, amikor a GC áthelyezte az objektumot, nem tudta, hogyan kell frissíteni a periféria konfigurációs regiszterében található mutatót.
Tehát most mozdulatlan DMA pufferek és GC által kezelt objektumok keverékére lenne szükség, ami azt jelenti, hogy mindkettőnek vannak hátrányai.
Megjegyzések
- Vitathatatlanul mindkettő összes hátránya, de az egyes hátrányok száma kevesebb, és ugyanaz az előnye. Nyilvánvaló, hogy bonyolultabb a memóriakezelés több fajtája, de elkerülhető az is, ha a kódon belül minden kurzushoz megfelelő lovat választunk. Nem valószínű, azt képzelem, de ' elméleti hiányosság van ott. Korábban ' spekuláltam a GC és a nem GC ugyanazon a nyelven történő keverésével, de nem eszközillesztők esetében – inkább azért, mert többnyire GC-s alkalmazás van, de néhány kézzel kezelt memóriával kevés szintű adatszerkezeti könyvtárak.
- @ Steve314: Nem mondaná ' t, hogy azt állítja, hogy mely objektumokat kell manuálisan felszabadítani, ugyanolyan megterhelő, mint emlékezni arra, hogy mindent kiszabadítson? (Természetesen az intelligens mutatók bármelyikben segíthetnek, így egyik sem jelent hatalmas problémát.) Különböző készletekre van szükség a manuálisan kezelt objektumokhoz, illetve az összegyűjtött / kompatibilis objektumokhoz, mivel a tömörítés nem ' t akkor működnek jól, ha fix tárgyak vannak szétszórva. Tehát sok extra bonyolultság a semmiért.
- Nem, ha ' egyértelmű különbség van a magas szintű kód, amely mind GC, és az alacsony szintű kód, amely kiválik a GC-ből. Főleg az ötletet dolgoztam ki, amikor néhány évvel ezelőtt néztem a D-t, amely lehetővé teszi, hogy kilépjen a GC-ből, de nem engedi, hogy ' visszalépjen. Vegyünk például egy B + fa könyvtárat . A tároló egészének GC-nek kell lennie, de az adatszerkezeti csomópontok valószínűleg nem – ' hatékonyabb, ha testreszabott vizsgálatot végeznek csak a levélcsomópontokon keresztül, mint arra, hogy a GC-t rekurzív keresés az ágcsomópontokon keresztül. Ennek a vizsgálatnak azonban be kell jelentenie a benne lévő elemeket a GC-nek.
- A lényeg az, hogy ' egy funkcionalitás része. A B + fa csomópontok speciális WRT memóriakezelésként való kezelése nem különbözik attól, hogy különleges WRT lét B + fa csomópontként kezeljük őket. ' s egy kapszulázott könyvtár, és az alkalmazás kódjának nem kell ' tudnia, hogy a GC viselkedését megkerülték / speciális esetben.Kivéve, hogy legalábbis abban az időben ez lehetetlen volt a D-ben – mint mondtam, semmiképpen sem választhat vissza, és jelentheti a benne lévő elemeket a GC-nek, mint potenciális GC-gyökereknek.
Válasz
Mivel a C & C ++ viszonylag alacsony szintű, általános célú nyelvek, még például futtatni egy 16 bites processzoron, 1 MB memóriával egy beágyazott rendszerben, ami nem engedheti meg magának a memória pazarlását a gc-vel.
Megjegyzések
- " Beágyazott rendszer "? A C szabványosításakor (1989) a PC-k 1 MB memóriával.
- Egyetértek, egy aktuálisabb példát hoztam.
- 1 MB ??? Szent schmoley, kinek lenne valaha szüksége ekkora RAM-ra? < / billGates >
Válasz
A C ++ – ban és a C-ben vannak szemétszedők. Nem biztos, hogy ez működik C-ben, de a C ++ – ban kihasználhatja az RTTI funkciót az objektumdiagram dinamikus felfedezéséhez és a szemétszállításhoz.
Tudomásom szerint nem írhat Java-t. szemétszedő nélkül. Egy kis keresés megalapozta ezt .
A legfontosabb különbség a Java és a C / C ++ között az, hogy a C / C ++ verzióban mindig a választás , míg a Java-ban gyakran opció nélkül marad a tervezés.
Megjegyzések
- És hogy a dedikált szemétszedők jobban megvalósíthatók, hatékonyabbak és jobban illeszkedjen a nyelvbe. 🙂
- Nem, ' nem használhatja az RTTI-t az objektumdiagram dinamikus felfedezéséhez a C / C ++ nyelven: It ' s a sima régi adatobjektumok, amelyek mindent elrontanak. Egyszerű régi adatobjektumban egyszerűen nincsenek tárolva olyan RTTI-információk, amelyek lehetővé tennék a szemétszedők számára, hogy megkülönböztessék az objektumon belül a mutatókat és a nem mutatókat. Még ennél is rosszabb, hogy a mutatókat nem kell tökéletesen összehangolni az összes hardverrel, ezért egy 16 bájtos objektum esetén 9 lehetséges hely található, amelyekben egy 64 bites mutató tárolható, ebből csak kettő don ' t átfedik egymást.
Válasz
Ez kompromisszumot jelent a teljesítmény és a biztonság között.
Nincs garancia arra, hogy a szemetet Java-ban gyűjtik össze, ezért lehet, hogy sokáig lóg a hely felhasználásánál, miközben a hivatkozás nélküli objektumok (azaz a szemét) beolvasása is hosszabb ideig tart, mint egy fel nem használt objektum kifejezett törlése vagy felszabadítása.
Az előny természetesen az, hogy lehet nyelvet építeni mutatók vagy memóriaszivárgások nélkül, így valószínűbb, hogy helyes kódot készít.
Ezeknek a vitáknak néha lehet egy kis “vallási” él – figyelmeztetni kell!
Válasz
Itt van egy lista a GC eredendő problémáiról, amelyek használhatatlanná teszik egy olyan rendszernyelven, mint a C:
-
A GC-nek a kód szintje alatt kell futnia, amelynek objektumait kezeli. Egy ilyen kernelben egyszerűen nincs ilyen szint.
-
A GC-nek időről időre le kell állítania a kezelt kódot. Gondoljon most arra, hogy mi történne, ha ezt tenné a kernelével. A gépén minden feldolgozás leáll, mondjuk, egy ezredmásodpercre, míg a GC az összes létező memória-allokációt átvizsgálja. Ez megölne minden olyan kísérletet, amely szigorú, valós idejű követelmények szerint működő rendszerek létrehozására irányul.
-
A GC-nek képesnek kell lennie megkülönböztetni a mutatókat és a nem mutatókat. Vagyis képesnek kell lennie minden létező memóriaobjektum megnézésére, és képesnek kell lennie az eltolások listájának elkészítésére, ahol a mutatói megtalálhatók.
Ennek a felfedezésnek tökéletesnek kell lennie: A GC-nek képesnek kell lennie üldözni az összes felfedezett mutatót. Ha hamis pozitívra utal, valószínűleg összeomlik. Ha nem találna hamis negatívumot, akkor valószínűleg megsemmisítene egy olyan objektumot, amely még mindig használatban van, összeomlik a kezelt kód vagy csendesen megrongálja az adatait.
Ehhez feltétlenül szükség van arra, hogy a típusinformációkat minden egyes tárolja létező objektum. A C és a C ++ mindazonáltal lehetővé teszi a régi, egyszerű típusú objektumok használatát, amelyek nem tartalmaznak típusinformációt.
-
A GC eleve lassú üzlet. A Java-val szocializált programozók Lehet, hogy ezt nem veszik észre, de a programok nagyságrendekkel gyorsabbak lehetnek, ha azokat nem hajtják végre a Java-ban. És a Java-t az egyik tényező lassítja a GC. Ez kizárja, hogy a GCed nyelvek, mint például a Java, szuperszámítógépekben használják. Ha a géped Évente egymillióba kerül energiafogyasztásban, ennek még a 10% -át sem akarja fizetni a szemétszállításért.
A C és a C ++ nyelvek, amelyek támogatást hoztak létre minden lehetséges felhasználási eset. És amint látja, sok ilyen felhasználási esetet kizár a szemétszállítás. Tehát e felhasználási esetek támogatása érdekében a C / C ++ nem gyűjthető szemétbe.