Komentáře
- V tomto semestru jsme dostali ' modul pro vývoj iPhone. Po kódování aplikací pro Android po dobu 2 let tato otázka zasáhla většinu třídy docela tvrdě. Teprve teď vidíme, kolik hodin nám Java skutečně ušetřila, když jsme nemuseli vysledovat ošklivé chyby ve správě paměti a nemuseli jsme psát kód kotlové desky.
- @NullUserException, protože to ' neurčit způsob, jak získat zpět paměť, která do značné míry implikuje GC.
- @ bizso09: Už jste se na ARC podívali? Když máte ' systémovou podporu pro počítání referencí, není potřeba pomalý / tlustý / nedeterministický GC: developer.apple. com / technologies / ios5
- Odpovědi na tuto docela dobrou otázku jsou plné náboženských keců.
- V C a C ++ je možné vzít ukazatel, vrhnout ho přidat a přidat k tomu číslo. Později odečtěte číslo z int a vraťte výsledek zpět na ukazatel. Získáte stejný ukazatel jako dříve. Hodně štěstí při implementaci GC, který NENÍ shromažďuje tuto paměť, zatímco její adresa je uložena pouze v proměnné, která má také jinou hodnotu. Vím, že příklad je hloupý, ale XOR propojený seznam používá něco podobného. Zveřejnil bych to jako odpověď, ale otázka je uzavřena.
Odpověď
Sběr odpadu vyžaduje datové struktury pro sledování alokací a / nebo počítání referencí. Ty vytvářejí režii v paměti, výkonu a složitosti jazyka. C ++ je navržen tak, aby byl „blízký kovu“, jinými slovy, přebírá vyšší výkonnost funkcí kompromisu a pohodlí. Jiné jazyky tento kompromis odlišují. To je jedna z úvah při výběru jazyka, kterému důrazu dáváte přednost.
To znamená, že v C ++ existuje spousta schémat pro počítání referencí, které jsou poměrně lehké a výkonné, ale jsou v knihovnách, komerčních i otevřených, spíše než součástí samotného jazyka. Počítání referencí pro správu životnosti objektu není stejné jako sběr odpadků, ale řeší mnoho stejných druhů problémů a lépe zapadá do základního přístupu C ++.
Komentáře
- Sekundárním problémem je, že GC je nedeterministický. Objekt může nebo nemusí být stále v paměti dlouho poté, co program " spadl " it. Životní cykly vrácení peněz jsou deterministické, když je zrušena poslední reference, je zrušena paměť. To má důsledky nejen pro účinnost paměti, ale také pro ladění. Běžná chyba programování je objekt " zombie ", referenční paměť, která byla teoreticky vypuštěna. GC mnohem pravděpodobněji maskuje tento efekt a produkuje chyby, které jsou přerušované a je extrémně obtížné je vypátrat.
- – moderní gc ' ani nesledují přidělení, ani nepočítají odkazy. Vytvářejí graf od předvečer vše, co je aktuálně v zásobníku, a jen kondenzujte a vymažte vše ostatní (zjednodušené) a GC má obvykle za následek sníženou jazykovou složitost. Dokonce i výhoda výkonu je sporná.
- Eh, @kylben, celý bod automatického GC zapečeného do jazyka je ten, že je nemožné odkazovat na zombie objekty, protože GC uvolní pouze objekty, na které nelze odkazovat! Když uděláte chybu při ruční správě paměti, získáte ty těžko sledovatelné chyby, o kterých ' mluvíte.
- -1, GC se nepočítá Reference. Navíc, v závislosti na vašem využití paměti a schématu přidělování, může být GC rychlejší (s režií využití paměti). Takže argument o výkonu je také klam. Platný bod je ve skutečnosti pouze blízký kovu.
- Ani Java, ani C # nepoužívají počítání referencí: Schémata GC založená na počítání referencí jsou ve srovnání docela primitivní a fungují mnohem horší než moderní sběrači odpadků (hlavně proto, že je třeba dělat zápisy do paměti, abyste změnili počty referencí, kdykoli zkopírujete referenci!)
Odpověď
Přísně vzato, v jazyce C není vůbec žádná správa paměti. malloc () a free () nejsou klíčová slova v jazyce, ale pouze funkce, které jsou volány z knihovny.Tento rozdíl může být nyní pedantický, protože malloc () a free () jsou součástí standardní knihovny C a budou poskytovány jakoukoli standardní implementací C vyhovující standardu, ale v minulosti to vždy neplatilo.
Proč byste chtěli jazyk, který nemá žádný standard pro správu paměti? To se vrací k počátkům jazyka C jako „přenosná sestava“. Existuje mnoho případů hardwaru a algoritmů, které mohou těžit nebo dokonce vyžadují speciální techniky správy paměti. Pokud vím, neexistuje způsob, jak úplně deaktivovat správu nativní paměti Java a nahradit ji vlastní. To je prostě nepřijatelné v některých situacích s vysokým výkonem / minimálním prostředkem. C poskytuje téměř úplnou flexibilitu při výběru přesné infrastruktury váš program bude používat. Zaplacená cena je, že jazyk C poskytuje jen velmi malou pomoc při psaní správného bezchybného kódu.
Komentáře
- +1 jeden pro celkovou dobrou odpověď, ale také zejména pro " Zaplacená cena je, že jazyk C poskytuje velmi malou pomoc při psaní správného bezchybného kódu "
- C má správu paměti – ale funguje to, takže si to lidé sotva všimnou. ' má statickou paměť, registry a stack. Dokud nezačnete přidělovat z haldy, jste ' v pohodě a dandy. ' je to halda, která věci pokazí . Tak jako pro Javu může každý napsat svůj vlastní runtime Java – ' je spousta na výběr, včetně toho, co by se dalo nazvat " Systém ' s Java ". .NET umí skoro všechno, co C dokáže – zaostává pouze za nativními schopnostmi C ++ ' (např. Třídy jsou spravovány pouze v .NET). Samozřejmě máte také C ++. NET, který má vše, co C ++ dělá, a všechno .NET.
- @Luaan I ' říkám, že ' je velmi velkorysá definice správy " správy paměti " " Dokud nezačnete přidělovat z haldy, jste ' v pořádku a dandy. Je to ' s alokací haldy, která věci pokazí ", což ' rád říká auto je naprosto dobré letadlo, prostě není ' schopné létat.
- @ CharlesE.Grant No, čistě funkční jazyk s tím dokáže všechno. druh správy paměti. Jen proto, že alokace haldy je v některých případech dobrým kompromisem, ' to neznamená, že ' je měřítkem pro všechny jazyky / runtime . ' Nelíbí se správa paměti, přestává být " správa paměti " jen proto, že ' jednoduchý, přímočarý, skrytý v zákulisí. Navrhování přidělování statické paměti je stále správa paměti, stejně jako dobré využití zásobníku a všeho, co máte k dispozici.
- " implementace vyhovující standardu " není pravda, pouze pro implementaci standardního hostitelského prostředí. Některé platformy / standardní knihovny, většinou pro 8 nebo 16bitový mikrokontrolér, neposkytují
malloc()
nebofree()
. (příkladem jsou kompilátory MLAP pro PIC)
Odpověď
Skutečnou odpovědí je jediný způsob, jak bezpečným a efektivním mechanismem sběru odpadu je mít podporu na jazykové úrovni pro neprůhledné odkazy. (Nebo naopak nedostatek podpory jazykové úrovně pro přímou manipulaci s pamětí.)
Java a C # to dokážou, protože mají speciální typy odkazů, se kterými nelze manipulovat. To dává modulu runtime svobodu dělat věci jako přesouvat přidělené objekty v paměti , což je pro vysoce výkonnou implementaci GC zásadní .
Pro záznam žádná moderní implementace GC nepoužívá počítání odkazů , takže je to úplně červená sleď. Moderní GC používají generační kolekci, kde se s novými alokacemi zachází v podstatě stejně jako s alokacemi zásobníku v jazyce, jako je C ++, a pak se pravidelně všechny nově přidělené objekty, které jsou stále naživu, přesouvají do samostatného prostoru pro přežití a celá generace objektů je uvolněno najednou.
Tento přístup má klady a zápory: výhodou je, že přidělení haldy v jazyce, který podporuje GC, jsou stejně rychlé jako přidělení zásobníku v jazyce, který nepodporuje GC, a nevýhodou je, že objekty, které potřebují provést vyčištění před zničením, vyžadují samostatný mechanismus (např. C #“ s using
klíčové slovo) nebo jinak jejich čisticí kód běží nedeterministicky.
Všimněte si, že jedním klíčem k vysoce výkonnému GC je, že musí existovat jazyková podpora pro speciální třídu odkazů. C nemá tuto jazykovou podporu a nikdy nebude; protože C ++ má přetížení operátoru, mohlo by emulovat typ ukazatele GC „d, i když by to muselo být provedeno opatrně. Ve skutečnosti, když Microsoft vynalezl svůj dialekt jazyka C ++, který by běžel pod CLR (.NET runtime), musel vymyslet novou syntaxi pro „odkazy ve stylu C #“ (např. Foo^
) odlišit je od „odkazů ve stylu C ++“ (např. Foo&
).
Co C ++ má a co programátoři C ++ pravidelně používají, je inteligentní ukazatele , které jsou ve skutečnosti jen mechanismem počítání referencí. Nechtěl bych považovat počítání referencí za „opravdový“ GC, ale poskytuje mnoho stejných výhod za cenu pomalejšího výkonu než manuální správa paměti nebo skutečný GC, ale s výhodou deterministického ničení.
Na konci dne se odpověď opravdu scvrkává na funkci jazykového designu. C udělala jednu volbu, C ++ udělala volbu, která jí umožnila zpětně kompatibilní s C a přitom poskytla alternativy, které jsou dost dobré pro většina účelů a Java a C # si vybrali jinou volbu, která je nekompatibilní s C, ale je pro většinu účelů také dost dobrá. Bohužel neexistuje žádná stříbrná kulka, ale znalost různých možností vám pomůže vybrat ten správný pro jakýkoli program, který se právě pokoušíte vytvořit.
Komentáře
- Toto je skutečná odpověď na otázku
- pro část c ++, dnes byste se měli podívat na std :: unique_ptr a std :: move 🙂
- žádný moderní GC implem entace používá počítání referencí : cPython používá počítání referencí i automatické shromažďování .
- @ Mike76: Na straně alokace bude alokátor GC pracovat přibližně stejně rychle jako alokace zásobníku a GC může přidělit tisíce objektů najednou. Bez ohledu na to, co děláte s implementací počítání ref, přidělení a uvolnění nikdy nebude rychlejší než
malloc
afree
. Takže ano, GC může být podstatně rychlejší. (Všimněte si, že jsem řekl, že " může být " – přesný výkon každého programu samozřejmě ovlivňuje mnoho faktorů.) - žádná moderní implementace GC nepoužívá počítání referencí Swift používá automatické počítání referencí.
odpověď
Protože při použití výkonu C ++ není potřeba.
Herb Sutter:“ V letech jsem nepsal mazání. “
viz Psaní moderního kódu v C ++: jak se C ++ v průběhu let vyvíjel 21:10
Může to překvapit mnoho zkušení programátoři v C ++.
Komentáře
- Zajímavé. Můj čtecí materiál pro dnešek.
- Bah, video. Ale to už je méně zajímavé.
- zajímavé video. 21 minut dovnitř a 55 minut dovnitř byly nejlepší kousky. Škoda, že volání WinRT stále vypadala jako bumpf C ++ / CLI.
- @ dan04: To je ' pravda. Ale pak, pokud píšete v jazyce C, získáte to, co požadujete.
- Správa inteligentních ukazatelů není o nic náročnější než zajistit, abyste ' t mít zbytečné odkazy v prostředí sběru odpadků. Protože GC nemůže ' přečíst vaši mysl, ' to také není magické.
Odpověď
„Vše“, kterým je garbage collector, je proces, který pravidelně běží a kontroluje, zda v paměti nejsou nějaké neodkazované objekty a zda jsou odstraněny. (Ano, vím, že se jedná o hrubé zjednodušení). Toto není vlastnost jazyka, ale rámec.
Existují sběrači odpadků napsaní pro C a C ++ – tento například .
Jedním z důvodů, proč člověk do jazyka nebyl „přidán“, může být velký objem existujícího kódu, který by jej nikdy nepoužíval, protože pro správu paměti používá svůj vlastní kód. Dalším důvodem je možné, že typy aplikací napsaných v C a C ++ nepotřebují režii spojenou s procesem sběru odpadků.
Komentáře
- Ale budoucí programy psaný by začal používat sběrače odpadků, ne?
- Zatímco sběr odpadků je teoreticky nezávislý na jakémkoli programovacím jazyce, je docela těžké napsat užitečný GC pro C / C ++, a dokonce je nemožné ho vyrobit jako bláznivý (alespoň stejně spolehlivý jako Java ' s) – důvodem, proč to Java dokáže vytáhnout, je to, že běží v kontrolovaném virtualizovaném prostředí. Naopak jazyk Java je určen pro GC a vy ' budete mít potíže s psaním kompilátoru Java, který ' nedělá GC .
- @tdammers: Souhlasím s tím, že aby bylo možné, musí být odvoz odpadu podporován jazykem. Hlavním bodem však není virtualizace a řízené prostředí, ale přísné psaní. C a C ++ jsou slabě napsané, takže umožňují věci, jako je ukládání ukazatele v celočíselné proměnné, rekonstrukce ukazatelů z posunů a takové věci, které brání tomu, aby kolektor mohl spolehlivě říci, čeho je dosažitelné (C ++ 11 zakazuje pozdějšímu povolení alespoň konzervativní sběratelé). V Javě vždy víte, co je reference, takže ji můžete sbírat přesně, i když je kompilován do nativního.
- @Thorbj ø rnRavnAndersen: Mohu napsat platný program C, který ukládá ukazatele takovým způsobem, že je žádný sběrač odpadků nemohl nikdy najít. Pokud by jste potom zapojili sběratele odpadků do
malloc
afree
, porušili byste můj správný program. - @Thorbj ø rnRavnAndersen: Ne, ' nebudu volat
free
, dokud s tím nebudu hotový . Ale váš navrhovaný sběrač odpadků, který ' neuvolní paměť, dokud výslovně nezavolámfree
isn ' ta garbage collector vůbec.
odpověď
C byl navržen v době, kdy sbírání odpadu bylo stěží možnost. To bylo také určeno pro použití, kde by odpadky obecně nefungovaly – holý kov, prostředí v reálném čase s minimální pamětí a minimální podporou běhu. Nezapomeňte, že C byl implementační jazyk pro první unix, který běžel na pdp-11 s 64 * K * bajty paměti. C ++ bylo původně rozšířením C – výběr již byl proveden a je velmi těžké naroubovat sběr odpadků do existujícího jazyka. Je to ten druh věci, který musí být zabudován z přízemí.
Odpověď
Nemám přesné uvozovky, ale Bjarne i Herb Sutter říkají něco v tomto smyslu:
C ++ nepotřebuje sběrač odpadků, protože nemá odpadky.
V moderní V C ++ používáte inteligentní ukazatele, a proto nemáte žádné odpadky.
Komentáře
- co jsou inteligentní ukazatele?
- pokud to bylo to jednoduché, nikdo by neimplementoval žádnou GC.
- @deadalnix: Správně, protože nikdo nikdy neimplementuje nic příliš komplikovaného, pomalého, nafouklého nebo zbytečného. Celý software je po celou dobu stoprocentně efektivní, že?
- @deadalnix – přístup ke správě paměti v C ++ je novější než garbage collectors. RAII vynalezl Bjarne Stroustrup pro C ++. Vyčištění destruktoru je starší myšlenka, ale klíčová jsou pravidla pro zajištění bezpečnosti výjimek. Nevím ' kdy přesně byl poprvé popsán samotný nápad, ale první standard C ++ byl dokončen v roce 1998 a Stroustrups " Design a vývoj C ++ " nebyl ' publikován do roku 1994 a výjimky byly relativně nedávným přírůstkem do C ++ – po vydání " Anotovaný referenční manuál C ++ " v roce 1990, věřím. GC bylo vynalezeno v roce 1959 pro Lisp.
- @deadalnix – víte, že alespoň jeden Java VM používal GC počítající odkazy, který mohl (téměř) být implementován pomocí RAII ve stylu C ++ pomocí třídy inteligentního ukazatele – přesně protože to bylo pro multithreadový kód efektivnější než stávající virtuální počítače? Viz www.research.ibm.com/people/d/dfb/papers/Bacon01Concurrent.pdf. Jedním z důvodů, proč to v praxi v jazyce C ++ nevidíte ', je obvyklá kolekce GC – může sbírat cykly, ale ' si vybrat bezpečné pořadí destruktoru za přítomnosti cyklů, a proto nemůže zajistit spolehlivé vyčištění destruktoru.
Odpovědět
Vy zeptejte se, proč tyto jazyky nebyly aktualizovány tak, aby obsahovaly volitelný garbage collector.
Problém s volitelným garbage collectorem je, že nemůžete kombinovat kód, který používá různé modely. To znamená, že když napíšu kód, který předpokládá, že používáte sběrač odpadků, nemůžete jej použít ve svém programu, který má vypouštění odpadků. Pokud to uděláte, bude to všude unikat.
Odpověď
Existují různé problémy, včetně …
- Ačkoli byl GC vynalezen před C ++ a možná i před C, byly C i C ++ implementovány dříve, než byly GC všeobecně přijímány jako praktické.
- Nelze snadno implementovat Jazyk a platforma GC bez základního jazyka jiného než GC.
- Ačkoli je GC pro typické aplikační kódy prokazatelně účinnější než jiné než GC vyvinuté v typických časových harmonogramech atd., Existují problémy, kde je více úsilí v oblasti vývoje dobrým obchodem -off a specializovaná správa paměti překoná univerzální GC. Kromě toho je C ++ obvykle prokazatelně efektivnější než většina jazyků GC, a to i bez dalšího úsilí o vývoj.
- GC není univerzálně bezpečnější než RAII ve stylu C ++ . RAII umožňuje automatické vyčištění jiných zdrojů než paměti, v zásadě proto, že podporuje spolehlivé a včasné destruktory. Nelze je kombinovat s konvenčními metodami GC kvůli problémům s referenčními cykly.
- Jazyky GC mají svou vlastní charakteristiku druhy paměti úniky, zejména v souvislosti s pamětí, která už nikdy nebude použita, ale tam, kde existovaly existující odkazy, které nebyly nikdy vynulovány nebo přepsány. Potřeba provést to výslovně se v zásadě neliší od potřeby výslovně
delete
nebofree
. Přístup GC má stále výhodu – žádné houpající se odkazy – a statická analýza může zachytit některé případy, ale opět neexistuje žádné perfektní řešení pro všechny případy.
V zásadě částečně “ Je to o stáří jazyků, ale i tak bude vždy místo pro jazyky jiné než GC – i když je to trochu zvláštní místo. A vážně, v C ++ není nedostatek GC velký problém – vaše paměť je spravována odlišně, ale není nespravovaná.
Microsofts spravovaný C ++ má alespoň nějakou schopnost kombinovat GC a ne- GC ve stejné aplikaci, což umožňuje kombinaci výhod každé z nich, ale nemám zkušenosti s tím, jak dobře to funguje v praxi.
Odkazy na související odpovědi na související odpovědi moje …
- 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
Odpověď
Dokážete si představit, že byste psali obslužnou rutinu zařízení v jazyce s odvozem odpadu? Kolik bitů by mohlo linka, zatímco běžel GC?
Nebo operační systém? Jak byste mohli spustit běžící sběr odpadu ještě před spuštěním jádra?
C je navrženo pro nízkou úroveň blízkou hardwarovým úlohám. Problém? je to tak pěkný jazyk, že je to dobrá volba i pro mnoho úkolů na vyšší úrovni. Jazykoví caři si jsou tohoto použití vědomi, ale musí prioritně podporovat požadavky na ovladače zařízení, vestavěný kód a operační systémy.
Komentáře
- C vhodné pro vysokou úroveň? Šňupal jsem si drink po celé klávesnici.
- No, řekl " mnoho úkolů vyšší úrovně ". Mohl počítat trolly (jeden, dva, mnoho …). A ve skutečnosti neřekl ' vyšší než co. Vtipy stranou, to je ale ' pravda – důkazem je, že mnoho významných projektů vyšší úrovně bylo úspěšně vyvinuto v jazyce C. Možná existují lepší možnosti nyní pro mnoho z těchto projektů, ale fungující projekt je silnějším důkazem než spekulace o tom, co by mohlo být.
- Existují některé spravované operační systémy a ' fungují celkem dobře. Ve skutečnosti, když uděláte spravovaný celý systém, výkonnostní zásah z používání spravovaného kódu poklesne ještě níže, až bude rychlejší než nespravovaný kód ve scénářích z reálného života. Samozřejmě to jsou všechny " výzkumné OS " – tam ' není skoro nic způsob, jak zajistit jejich kompatibilitu s existujícím nespravovaným kódem, kromě vytvoření plně virtualizovaného nespravovaného OS v rámci spravovaného OS. Microsoft v určitém okamžiku navrhl, že by mohli nahradit Windows Server jedním z nich, protože stále více a více serverových kódů je napsáno na .NET.
Odpověď
Krátká a nudná odpověď na tuto otázku spočívá v tom, že pro lidi, kteří zapisují odpadky, musí existovat jazyk, který není shromažďován. Není koncepčně snadné mít jazyk, který současně umožňuje velmi přesnou kontrolu nad rozložením paměti a nahoře běží GC.
Další otázka je proč C a C ++ nemají sběrače odpadků.No, já vím, že C ++ jich má pár kolem, ale nejsou opravdu populární, protože jsou nuceni jednat s jazykem, který nebyl navržen tak, aby byl v první řadě GC-ed, a lidmi, kteří stále používají C ++ tento věk opravdu není ten typ, který by postrádal GC.
Také místo přidání GC do starého jazyka bez GC je skutečně snazší vytvořit nový jazyk, který má většinu stejná syntaxe při podpoře GC. Java a C # jsou toho dobrým příkladem.
Komentáře
- Někde na programmers.se nebo SO, tam ' tvrdí, že mi někdo řekl, že někdo pracuje na samo-bootstrappingu sebraných věcí – IIRC v zásadě implementuje VM pomocí jazyka GC, přičemž k implementaci samotného GC se používá podmnožina bootstrappingu . Zapomněl jsem jméno. Když jsem se na to podíval, ukázalo se, že ' d v zásadě nikdy nedosáhli skoku z podmnožiny bez GC na pracovní GC úroveň. je v zásadě možné, ale AFAIK toho v praxi nikdy nebylo dosaženo – ' určitě jde o to, dělat věci tvrdě.
- @ Steve314: I ' Rád bych viděl, že pokud si někdy budete pamatovat, kde jste jej našli!
- našli to! Přečtěte si komentáře k stackoverflow.com/questions/3317329/… odkazující na Klein VM. Část problému s nalezením – otázka byla uzavřena.
- BTW – zdá se mi, že nemohu začít komentovat pomocí @missingno – co dává?
- @ steve314: Po odpovědi na tuto otázku vlákno je připojeno, již dostávám upozornění na všechny komentáře. Dělat @ -post by v tomto případě bylo nadbytečné a SE to nepovoluje (ne ' se mě však proč neptejte). (Skutečnou příčinou je však to, že moje číslo chybí)
Odpověď
Sběr odpadu je zásadně nekompatibilní s systémový jazyk používaný pro vývoj ovladačů pro hardware podporující DMA.
Je zcela možné, že jediný ukazatel na objekt by byl uložen v hardwarovém registru na nějaké periferii. Protože garbage collector by nevěděl o tom by si myslel, že je objekt nedosažitelný, a shromáždil ho.
Tento argument platí dvojnásobně pro zhutnění GC. I když jste byli opatrní při udržování odkazů v paměti na objekty používané hardwarovými periferiemi, když GC přemístil objekt, nevěděl by, jak aktualizovat ukazatel obsažený v registru periferních konfigurací.
Takže nyní potřebujete směs nepohyblivých vyrovnávacích pamětí DMA a objektů spravovaných GC, což znamená, že máte všechny jejich nevýhody.
Komentáře
- Pravděpodobně všechny nevýhody obou, ale méně případů každé nevýhody a stejné výhody. Je zřejmé, že je složité zvládnout více druhů správy paměti, ale může se také vyhnout složitosti výběrem správného koně pro každý kurz v kódu. Nepravděpodobně si to představuji, ale existuje ' teoretická mezera. Předtím jsem ' spekuloval o smíchání GC a non-GC ve stejném jazyce, ale ne pro ovladače zařízení – spíše pro to, že mám většinou GC aplikaci, ale s nějakou ručně spravovanou pamětí knihovny datové struktury na úrovni.
- @ Steve314: Neříkáte ', že zapamatování si, které objekty je třeba ručně osvobodit, je stejně obtížné jako zapamatování si všeho uvolnit? (Inteligentní ukazatele samozřejmě mohou pomoci s oběma, takže ani jeden z nich není velkým problémem) A pro ručně spravované objekty a shromážděné / kompaktní objekty potřebujete různé fondy, protože zhutnění ' t fungují dobře, když jsou v nich rozptýleny pevné objekty. Takže spousta extra složitosti za nic.
- Ne, pokud existuje ' jasný rozdíl mezi kódem na vysoké úrovni, který je celý GC, a kódem na nízké úrovni kód, který se odhlásí z GC. Myšlenku jsem vyvinul hlavně při pohledu na D před několika lety, což vám umožňuje odhlásit se z GC, ale neumožňuje vám to ' přihlásit se zpět. Vezměte si například knihovnu stromů B + . Kontejner jako celek by měl být GC, ale uzly datové struktury pravděpodobně ne – ' je efektivnější provádět přizpůsobené skenování pouze prostřednictvím uzlů listu, než aby GC udělal rekurzivní vyhledávání přes uzly větví. Toto skenování však musí hlásit obsažené položky GC.
- Jde o to, že ' je obsažená funkce. Zacházení s uzly stromu B + jako se speciální správou paměti WRT se neliší od toho, jak s nimi zacházet jako se speciálními uzly stromu WRT bytí B +. ' Je to zapouzdřená knihovna a kód aplikace nemusí ' vědět, že chování GC bylo obejito / speciální.Až na to, že alespoň v té době to v D nebylo možné – jak jsem řekl, neexistuje způsob, jak se přihlásit zpět a nahlásit obsažené položky GC jako potenciální kořeny GC.
Odpověď
Protože C & C ++ jsou jazyky relativně nízké úrovně určené pro obecné účely, například běžet na 16bitovém procesoru s 1 MB paměti ve vestavěném systému, což by si nemohlo dovolit plýtvat pamětí pomocí gc.
Komentáře
- " Integrovaný systém "? V době, kdy byl standardizován program C (1989), bylo potřeba zvládnout počítače s 1 MB paměti.
- Souhlasím, citoval jsem aktuální příklad.
- 1 MB ??? Svatý schmoley, kdo by někdy potřeboval tolik RAM? < / billGates >
odpověď
V C ++ a C existují sběrači odpadků. Nejste si jisti, jak to funguje v C, ale v C ++ můžete využít RTTI k dynamickému objevení grafu objektu a jeho použití pro sběr odpadků.
Pokud vím, nemůžete psát Javu bez sběrače odpadků. Ukázalo se malé hledání toto .
Klíčový rozdíl mezi Javou a C / C ++ spočívá v tom, že v C / C ++ je výběr vždy na vás , vzhledem k tomu, že v Javě často zůstáváte bez návrhových možností.
Komentáře
- A také to, že vyhrazení garbage collectors jsou lépe implementováni, efektivnější a lépe zapadají do jazyka. 🙂
- Ne, ' nemůžete pomocí RTTI dynamicky objevit graf objektu v C / C ++: It ' s obyčejné staré datové objekty, které vše kazí. V prostém starém datovém objektu nejsou jednoduše uloženy žádné informace RTTI, které by sběrateli odpadků umožnily rozlišovat mezi ukazateli a ukazateli v tomto objektu. Ještě horší je, že ukazatele nemusí být dokonale zarovnány na veškerém hardwaru, takže vzhledem k 16 bajtovému objektu existuje 9 možných míst, kde lze uložit 64bitový ukazatel, pouze dvě z nich don ' t překrytí.
Odpověď
Je to kompromis mezi výkonem a bezpečností.
Neexistuje žádná záruka, že vaše odpadky budou shromážděny v Javě, takže může to být po dlouhou dobu viset a zabírat místo, zatímco skenování nereferenčních objektů (tj. odpadků) také trvá déle než explicitní odstranění nebo uvolnění nepoužívaného objektu.
Výhodou je samozřejmě to, že člověk si může vytvořit jazyk bez ukazatelů nebo bez úniku paměti, takže je pravděpodobnější, že vytvoří správný kód.
Někdy může mít tato debata mírný „náboženský“ náskok – varujte se!
Odpověď
Zde je seznam inherentních problémů GC, díky nimž je nepoužitelný v systémovém jazyce, jako je C:
-
GC musí běžet pod úrovní kódu, jehož objekty spravuje. V jádře prostě žádná taková úroveň neexistuje.
-
GC musí čas od času zastavit spravovaný kód. Nyní přemýšlejte o tom, co by se stalo, kdyby to udělalo vašemu jádru. Veškeré zpracování na vašem počítači by se zastavilo, řekněme, na milisekundu, zatímco GC skenuje všechna stávající přidělení paměti. To by zabilo všechny pokusy o vytvoření systémů, které fungují podle přísných požadavků v reálném čase.
-
GC musí být schopen rozlišovat mezi ukazateli a ukazateli, které nejsou ukazateli. To znamená, že musí být schopen podívat se na každý existující paměťový objekt a být schopen vytvořit seznam ofsetů, kde lze najít jeho ukazatele.
Tento objev musí být dokonalý: GC musí být schopen pronásledovat všechny ukazatele, které objeví. Pokud by to dereferences falešně pozitivní, to by pravděpodobně havaruje. Pokud by se nepodařilo zjistit falešný zápor, pravděpodobně by zničil objekt, který je stále používán, havaroval spravovaný kód nebo tiše poškodil jeho data.
To absolutně vyžaduje, aby informace o typu byly uloženy v každém jednotlivém objekt existuje. C i C ++ však umožňují prosté staré datové objekty, které neobsahují žádné informace o typu.
-
GC je ze své podstaty pomalé podnikání. Programátoři, kteří byli socializováni s Javou si to možná neuvědomují, ale programy mohou být řádově rychlejší, pokud nejsou implementovány v Javě. A jedním z faktorů, díky nimž je Java pomalá, je GC. To vylučuje použití jazyků GCed, jako je Java, v superpočítačích. stojí milion ročně spotřeby energie, nechcete platit ani 10% z toho za odvoz odpadu.
C a C ++ jsou jazyky, které jsou vytvořeny na podporu všechny možné případy použití. A jak vidíte, mnoho z těchto případů použití je vyloučeno pomocí uvolňování paměti. Abychom podpořili tyto případy použití, nelze C / C ++ shromažďovat odpadky.