Kommentarer
- Vi ' har fået et modul i iPhone-udvikling i dette semester. Efter kodning af apps til Android i 2 år ramte dette spørgsmål de fleste af klassen ret hårdt. Først nu ser vi, hvor mange timer Java faktisk har reddet os i ikke at skulle spore ubehagelige hukommelsesstyringsfejl og ikke behøver at skrive kedelpladekode.
- @NullUserException, da det ikke ' t angiv en måde at genvinde hukommelse på, der stort set indebærer en GC.
- @ bizso09: Så du på ARC endnu? Intet behov for langsom / fedt / ikke-deterministisk GC, når du ' har fået systemstøtte til referenceoptælling: developer.apple. com / teknologier / ios5
- Svarene på dette ret gode spørgsmål er fulde af religiøs lort.
- I C og C ++ er det muligt at tage en markør, kaste den til int og tilføj et nummer til det. Senere subtraherer tallet fra intet og kaster resultatet tilbage til en markør. Du får den samme markør som før. Held og lykke med implementeringen af en GC, der IKKE samler den hukommelse, mens dens adresse kun er gemt i variablen, som også har en anden værdi. Jeg ved, at eksemplet er fjollet, men en XOR-linket liste bruger noget lignende. Jeg vil sende dette som et svar, men spørgsmålet er lukket.
Svar
Affaldssamling kræver datastrukturer for sporing af allokeringer og / eller referencetælling. Disse skaber overhead i hukommelse, ydeevne og sprogets kompleksitet. C ++ er designet til at være “tæt på metallet”, med andre ord, det tager den højere ydelsesside af kompromis versus bekvemmelighedsfunktioner. Andre sprog gør denne kompromis anderledes. Dette er en af overvejelserne ved valg af sprog, hvilken vægt du foretrækker.
Når det er sagt, er der mange skemaer til referencetælling i C ++, der er ret lette og performante, men de findes i biblioteker, både kommercielle og open source, snarere end en del af selve sproget. Referenceoptælling til styring af objektets levetid er ikke det samme som affaldsindsamling, men det adresserer mange af de samme slags problemer og passer bedre sammen med C ++ s grundlæggende tilgang.
Kommentarer
- Et sekundært problem er, at GC ikke er deterministisk. Objektet kan eller ikke stadig være i hukommelsen længe efter, at programmet " er droppet " det. Refcount-livscyklusser er deterministiske, når den sidste reference slippes, tabes hukommelsen. Dette har ikke kun konsekvenser for hukommelseseffektivitet, men også for fejlretning. " zombie " objekt, referencehukommelse, der teoretisk er blevet droppet. GC er meget mere tilbøjelige til at maskere denne effekt og producere fejl, der er intermitterende og ekstremt vanskelige at spore.
- – moderne gc ' er hverken sporallokeringer eller tæller referencer. De bygger en graf fra aften rything i øjeblikket på stakken og kun kondenserer og tørrer alt andet (forenklet), og GC resulterer normalt i reduceret sprogkompleksitet. Selv ydelsesfordelen er tvivlsom.
- Er, @kylben, hele pointen med at have automatisk GC bagt ind i sproget er, at det bliver umuligt at henvise til zombieobjekter, fordi GC frigør kun objekter, som det er umuligt at henvise til! Du får den slags svære at spore bugs, du ' taler om, når du laver fejl med manuel hukommelsesadministration.
- -1, GC tæller ikke referencer. Plus, afhængigt af dit hukommelsesforbrug og tildelingsskema, kan en GC være hurtigere (med en overhead i hukommelsesforbruget). Så argumentet om ydeevne er også fejlslutning. Kun tæt på metallet er faktisk et gyldigt punkt.
- Hverken Java eller C # bruger referencetælling: GC-ordninger baseret på referencetælling er ret primitive i sammenligning og fungerer meget dårligere end moderne affaldssamlere (primært fordi de har brug for hukommelseskrivninger for at ændre referencetællinger, når du kopierer en reference!)
Svar
Strengt taget, der er slet ingen hukommelsesadministration på C-sproget. malloc () og free () er ikke nøgleord på sproget, men kun funktioner, der kaldes fra et bibliotek.Denne skelnen kan være pedantisk nu, fordi malloc () og gratis () er en del af C-standardbiblioteket og vil blive leveret af enhver standardkompatibel implementering af C, men det var ikke altid tilfældet tidligere.
Hvorfor vil du have et sprog uden standard til hukommelsesadministration? Dette går tilbage til Cs oprindelse som “bærbar samling”. Der er mange tilfælde af hardware og algoritmer, der kan drage fordel af eller endda kræve specialiserede hukommelsesstyringsteknikker. Så vidt jeg ved, er der ingen måde at deaktivere Javas indbyggede hukommelsesadministration og erstatte den med din egen. Dette er simpelthen ikke acceptabelt i nogle højtydende / minimale ressurssituationer. C giver næsten fuldstændig fleksibilitet til at vælge nøjagtigt hvilken infrastruktur dit program skal bruges. Den betalte pris er, at C-sproget giver meget lidt hjælp til at skrive korrekt, fejlfri kode.
Kommentarer
- +1 til det overordnede gode svar, men også især til " Den betalte pris er, at C-sproget giver meget lidt hjælp til at skrive korrekt, fejlfri kode "
- C har hukommelsesstyring – men det virker bare, så folk bemærker det næppe. Der ' s statisk hukommelse, registre og stack. Indtil du begynder at tildele ud af bunken, er du ' fin og skæl. Det ' er bunketildelingen, der ødelægger tingene . Som til Java kan alle skrive deres egen Java-runtime – der er ' masser at vælge imellem, inklusive hvad der kunne kaldes " System ' s Java ". .NET kan gøre stort set alt, hvad C kan – det hænger kun bag C ++ ' s native kapaciteter (f.eks. Klasser administreres kun i .NET). Selvfølgelig har du også C ++. NET, som har alt, hvad C ++ gør, og alt. NET gør.
- @Luaan I ' d siger, at ' en meget generøs definition af at have " hukommelsesstyring " " Indtil du begynder at tildele ud af bunken, er du ' fin og skæl. Det ' er bunketildelingen, der ødelægger tingene ", at ' er som at sige en bil er et perfekt godt fly, den er bare ikke ' ikke i stand til at flyve.
- @ CharlesE.Grant Nå, et rent funktionelt sprog kan gøre alt sammen med det slags hukommelsesstyring. Bare fordi bunktildeling i nogle brugssager er en god afvejning betyder ikke ' t, at det ' er benchmark for alle sprog / driftstider . Det ' er ikke som hukommelsesstyring holder op med at være " hukommelsesstyring " bare fordi det ' s enkle, ligetil, skjult bag kulisserne. At designe statisk hukommelsesallokering er stadig hukommelsesstyring, ligesom en god brug af stakken og hvad du ellers har til rådighed.
- " enhver standardkompatibel implementering " er ikke sandt, kun for standardkompatibel værtsmiljøimplementering. Nogle platforme / standardbiblioteker, de fleste til 8 eller 16-bit integreret mikrokontroller, leverer ikke
malloc()
ellerfree()
. (eksempel er MLAP-kompilatorer til PIC)
Svar
Det virkelige svar er, at den eneste måde at gøre en sikker, effektiv skraldopsamlingsmekanisme er at have sprogstøtte til uigennemsigtige referencer. (Eller omvendt en mangel på sprogniveaustøtte til direkte hukommelsesmanipulation.)
Java og C # kan gøre det, fordi de har specielle referencetyper, der ikke kan manipuleres. Dette giver runtime friheden til at gøre ting som flytte tildelte objekter i hukommelsen , hvilket er afgørende for en højtydende GC-implementering .
For ordens skyld bruger ingen moderne GC-implementering referencetælling , så det er helt rødt sild. Moderne GCer bruger generationssamling, hvor nye allokeringer behandles i det væsentlige på samme måde som stakallokeringer er på et sprog som C ++, og derefter flyttes periodisk alle nyligt allokerede objekter, der stadig er i live, til et separat “overlevende” rum og en hel generation af genstande omplaceres på én gang.
Denne tilgang har fordele og ulemper: opadrettede er, at bunktildelinger på et sprog, der understøtter GC, er så hurtigt som stakallokeringer på et sprog, der ikke understøtter GC, og ulempen er, at objekter, der skal udføre oprydning inden ødelæggelse, enten kræver en separat mekanisme (f.eks. C #” s using
nøgleord) ellers kører deres oprydningskode ikke-deterministisk.
Bemærk, at en nøgle til en højtydende GC er, at der skal være sprogstøtte til en særlig referenceklasse. C har ikke denne sprogstøtte og vil aldrig; fordi C ++ har overbelastning af operatøren, kan den efterligne en GC “d-markørtype, selvom det skulle gøres omhyggeligt. Når Microsoft opfandt deres dialekt af C ++, der ville køre under CLR (.NET runtime), måtte de faktisk opfinde en ny syntaks til “C # -stil referencer” (f.eks. Foo^
) for at skelne dem fra “C ++ – stilreferencer” (f.eks. Foo&
).
Hvad C ++ har, og hvad der regelmæssigt bruges af C ++ – programmører, er smarte pointer , som egentlig bare er en referencetællingsmekanisme. Jeg vil ikke betragte referencetælling som “sand” GC, men det giver mange af de samme fordele på bekostning af langsommere ydeevne end enten manuel hukommelsesstyring eller ægte GC, men med fordelen ved deterministisk destruktion.
I slutningen af dagen koges svaret virkelig til en sprogdesignfunktion. C foretog et valg, C ++ foretog et valg, der gjorde det muligt at være bagudkompatibel med C, mens de stadig leverede alternativer, der er gode nok til de fleste formål, og Java og C # tog et andet valg, der er uforeneligt med C, men som også er godt nok til de fleste formål. Desværre er der ingen sølvkugle, men at være fortrolig med de forskellige valg derude vil hjælpe dig med at vælge den rigtige uanset hvilket program du i øjeblikket prøver at bygge.
Kommentarer
- Dette er det egentlige svar på spørgsmålet
- For c ++ -delen, i dag skal du se på std :: unique_ptr og std :: move 🙂
- intet moderne GC-implem entation bruger referencetælling : cPython bruger både referencetælling og automatisk samling .
- @ Mike76: På tildelingssiden vil en GC-tildeler arbejde lige så hurtigt som stakallokering, og GC kan omfordele tusindvis af objekter på samme tid. Uanset hvad du gør med en ref-count-implementering, vil tildeling og deallocation aldrig være hurtigere end
malloc
ogfree
. Så ja, en GC kan være væsentligt hurtigere. (Bemærk at jeg sagde " kan være " – selvfølgelig påvirkes den nøjagtige ydeevne for hvert program af mange faktorer.) - ingen moderne GC-implementering bruger referencetælling Swift bruger automatisk referencetælling.
Svar
Fordi når du bruger kraften i C ++, er der ikke noget behov.
Herb Sutter:” Jeg har ikke skrevet slette i år. ”
se Skrivning af moderne C ++ – kode: hvordan C ++ har udviklet sig gennem årene 21:10
Det kan overraske mange erfarne C ++ programmerere.
Kommentarer
- Interessant. Mit læsestof for i dag.
- Bah, en video. Men ikke desto mindre interessant allerede.
- interessant video. 21 minutter inde og 55 minutter inde var de bedste bits. Synd, at WinRT-opkaldene stadig så ud til at være C ++ / CLI bumpf.
- @ dan04: Det er '. Men så hvis du skriver i C, får du det, du beder om.
- Det er ikke mere krævende at styre de smarte markører end at sørge for, at du ikke ' t har unødvendige referencer i et affaldsindsamlet miljø. Fordi GC ikke kan ' t læser dit sind, er det ' heller ikke magisk.
Svar
“Alt”, som en affaldssamler er, er en proces, der løbende kontrollerer for at se, om der er nogen ikke-henviste objekter i hukommelsen, og om der er sletning af dem. (Ja, jeg ved, dette er en grov forenkling). Dette er ikke en egenskab for sproget, men rammen.
Der er skraldesamlere skrevet til C og C ++ – denne for eksempel .
En af grundene til, at man ikke “er blevet” tilføjet “til sproget, kan være på grund af den store mængde eksisterende kode, der aldrig ville bruge den, da de bruger deres egen kode til at styre hukommelsen. En anden årsag kunne være, at de typer applikationer, der er skrevet i C og C ++, ikke har brug for omkostningerne forbundet med en skraldopsamlingsproces.
Kommentarer
- Men fremtidige programmer skrevet ville begynde at bruge affaldssamleren, nej?
- Mens affaldssamling teoretisk er uafhængig af ethvert programmeringssprog, er det ret svært at skrive en nyttig GC til C / C ++ og endda umulig at lave en idiotsikker (mindst lige så idiotsikker som Java ' s) – grunden til, at Java kan trække det ud, er fordi det kører i et kontrolleret virtualiseret miljø. Omvendt er Java-sproget designet til GC, og du ' har svært ved at skrive en Java-compiler, der ikke ' ikke gør GC .
- @tdammers: Jeg er enig i, at affaldsindsamling skal understøttes af sproget for at være mulig. Imidlertid er hovedpunktet ikke virtualisering og kontrolleret miljø, men streng skrivning. C og C ++ er svagt skrevet, så de tillader ting som at gemme markøren i heltalsvariabler, rekonstruere markører fra forskydninger og sådanne ting, der forhindrer samleren i at være i stand til at fortælle pålideligt, hvad der kan nås (C ++ 11 forbyder senere at tillade mindst konservative samlere). I Java ved du altid, hvad der er en reference, så du kan indsamle den nøjagtigt, selvom den er kompileret til native.
- @Thorbj ø rnRavnAndersen: Jeg kan skrive en gyldigt C-program, der gemmer markører på en sådan måde, at ingen affaldssamler nogensinde kunne finde dem. Hvis du derefter tilslutter en affaldssamler til
malloc
ogfree
, ville du bryde mit rigtige program. - @Thorbj ø rnRavnAndersen: Nej, jeg ville ikke ' t kalde
free
indtil jeg var færdig med det . Men din foreslåede affaldssamler, der ikke ' ikke frigør hukommelsen, indtil jeg udtrykkeligt kalderfree
isn ' ta affaldssamler overhovedet.
Svar
C blev designet i en æra, hvor affaldssamlingen knap var en mulighed. Det var også beregnet til anvendelser, hvor affaldsindsamling generelt ikke fungerer – bare metal, miljøer i realtid med minimal hukommelse og minimal understøttelse af runtime. Husk at C var implementeringssprog for den første unix, der kørte på en pdp-11 med 64 * K * hukommelsesbyte. C ++ var oprindeligt en udvidelse af C – valget var allerede taget, og det er meget svært at pode affaldsindsamling på et eksisterende sprog. Det er den slags ting, der skal bygges ind fra stueetagen.
Svar
Jeg har ikke de nøjagtige citater, men både Bjarne og Herb Sutter siger noget i retning af:
C ++ har ikke brug for en affaldssamler, fordi den ikke har noget affald.
I moderne C ++ bruger du smarte pointer og har derfor ikke noget affald.
Kommentarer
- hvad er smarte pointer?
- hvis det var det enkelt, ingen ville have implementeret nogen GC.
- @deadalnix: Ret, fordi ingen nogensinde implementerer noget alt for kompliceret, langsomt, oppustet eller unødvendigt. Al software er 100% effektiv hele tiden, ikke?
- @deadalnix – C ++ tilgang til hukommelsesadministration er nyere end affaldssamlere. RAII blev opfundet af Bjarne Stroustrup til C ++. Oprydning af ødelæggere er en ældre idé, men reglerne for at sikre undtagelsessikkerhed er nøglen. Jeg ved ikke ' hvornår nøjagtigt hvornår idéen først blev beskrevet, men den første C ++ – standard blev afsluttet i 1998, og Stroustrups " Design og udvikling af C ++ " var ikke ' t offentliggjort indtil 1994, og undtagelser var en relativt ny tilføjelse til C ++ – efter offentliggørelsen af " Kommenteret C ++ referencehåndbog " i 1990 tror jeg. GC blev opfundet i 1959 for Lisp.
- @deadalnix – er du opmærksom på, at mindst en Java VM brugte en referencetælling GC, der (næsten) kunne implementeres ved hjælp af C ++ – stil RAII ved hjælp af en smart pointer-klasse – netop fordi det var mere effektivt til flertrådet kode end eksisterende VMer? Se www.research.ibm.com/people/d/dfb/papers/Bacon01Concurrent.pdf. En af grundene til at du ikke ' ikke ser dette i C ++ i praksis, er den sædvanlige GC-samling – den kan indsamle cyklusser, men kan ' ikke vælge en sikker destruktørordre i nærværelse af cyklusser og kan således ikke sikre pålidelig destruktøroprydning.
Svar
Dig spørg, hvorfor disse sprog ikke er opdateret til at omfatte en valgfri affaldssamler.
Problemet med valgfri affaldssamling er, at du ikke kan blande kode, der bruger de forskellige modeller. Det vil sige, hvis jeg skriver kode, der antager, at du bruger en affaldssamler, kan du ikke bruge den i dit program, hvor skraldespild er slået fra. Hvis du gør det, lækker det overalt.
Svar
Der er forskellige problemer, herunder …
- Selvom GC blev opfundet før C ++ og muligvis før C, blev både C og C ++ implementeret, før GC blev bredt accepteret som praktisk.
- Du kan ikke let implementere en GC-sprog og -platform uden et underliggende ikke-GC-sprog.
- Selvom GC påviseligt er mere effektiv end ikke-GC for typiske applikationskoder udviklet i typiske tidsskalaer osv., Er der problemer, hvor mere udviklingsindsats er en god handel -off og specialiseret hukommelsesadministration vil overgå en generel GC. Desuden er C ++ typisk påviseligt mere effektiv end de fleste GC-sprog selv uden nogen ekstra udviklingsindsats.
- GC er ikke universelt sikrere end C ++ – stil RAII RAII tillader, at andre ressourcer end hukommelse automatisk ryddes op, grundlæggende fordi den understøtter pålidelige og rettidige destruktorer. Disse kan ikke kombineres med konventionelle GC-metoder på grund af problemer med referencecykler.
- GC-sprog har deres egne karakteristika slags hukommelse lækager, især relateret til hukommelse, der aldrig vil blive brugt igen, men hvor der eksisterede eksisterende referencer, der aldrig er blevet ophævet eller overskrevet. Behovet for at gøre dette eksplicit er ikke anderledes i princippet end behovet for
delete
ellerfree
eksplicit. GC-tilgangen har stadig en fordel – ingen dinglende referencer – og statisk analyse kan fange nogle tilfælde, men igen er der ingen perfekt løsning til alle sager.
Grundlæggende, delvist det ” Det handler om alderen på sprogene, men der vil altid være et sted for ikke-GC-sprog – selvom det er lidt af et nichey-sted. Og seriøst, i C ++, er manglen på GC ikke en “big deal” – din hukommelse styres forskelligt, men den administreres ikke.
Cs med mikrosofter administreret har i det mindste en evne til at blande GC og ikke- GC i samme applikation, hvilket muliggør en blanding af fordelene fra hver, men jeg har ikke erfaring med at sige, hvor godt dette fungerer i praksis.
Gentagelse af links til relaterede svar af mig …
- 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
Svar
Kan du forestille dig at skrive en enhedshåndterer på et sprog med affaldssamling? Hvor mange bits kan komme ned linje, mens GC kørte?
Eller et operativsystem? Hvordan kunne du starte affaldsindsamlingen, før du overhovedet starter kernen?
C er designet til lavt niveau tæt på hardwareopgaverne. Problemet? er det sådan et godt sprog, at det også er et godt valg til mange højere niveauopgaver. Sprogzarerne er opmærksomme på disse anvendelser, men de skal understøtte kravene til enhedsdrivere, integreret kode og operativsystemer som en prioritet.
Kommentarer
- C god til højt niveau? Jeg fnysede min drink overalt på tastaturet.
- Nå, han sagde " mange højere opgaver ". Han kunne være troldoptælling (en, to, mange …). Og han sagde ikke ' t højere end hvad. Vittigheder til side er dog ' sandt – beviset er, at mange vigtige projekter på højere niveau er med succes blevet udviklet i C. Der kan være bedre valg nu for mange af disse projekter, men et arbejdsprojekt er stærkere bevis end spekulation om, hvad der kunne have været.
- Der er ' nogle administrerede operativsystemer, og de fungerer ret godt. Faktisk, når du gør hele systemet administreret, falder ydeevnen, der rammes af brugen af administreret kode, endnu lavere, indtil det er hurtigere end ikke-administreret kode i virkelige scenarier. Selvfølgelig er det alle " research OS " – der ' er stort set nej måde at gøre dem kompatible med eksisterende ikke-administreret kode udover at lave et fuldt virtualiseret ikke-administreret OS inden for det styrede OS. Microsoft foreslog på et eller andet tidspunkt, at de muligvis kunne erstatte Windows Server med en af disse, da flere og flere serverkoder skrives på .NET.
Svar
Det korte og kedelige svar på dette spørgsmål er, at der skal være et sprog, der ikke er affaldssamlet, derude for de mennesker, der skriver affaldssamlere. Det er ikke begrebsmæssigt let at have et sprog, der samtidig giver mulighed for meget nøjagtig kontrol over hukommelseslayoutet og har en GC, der kører på toppen.
Det andet spørgsmål er hvorfor C og C ++ ikke har affaldssamlere.Nå, jeg ved, at C ++ har et par af dem rundt, men de er ikke rigtig populære, fordi de er tvunget til at håndtere et sprog, der ikke var designet til at blive GC-ed i første omgang, og de mennesker, der stadig bruger C ++ i denne alder er ikke rigtig den slags, der savner en GC.
I stedet for at føje GC til et gammelt sprog, der ikke er GC-ed, er det faktisk lettere at oprette et nyt sprog, der har det meste af samme syntaks, mens du understøtter en GC. Java og C # er gode eksempler på dette.
Kommentarer
- Et eller andet sted på programmers.se eller SO, der ' er en påstand, nogen har gjort mig, at nogen arbejder på en selv-bootstrapping affaldssamlet ting – IIRC grundlæggende implementerer VM ved hjælp af et GC-sprog, med et bootstrapping-undersæt, der bruges til at implementere selve GC . Jeg glemmer navnet. Da jeg kiggede på det, viste det sig, at de ' dybest set aldrig nåede springet fra delsættet-uden-GC til arbejds-GC-niveauet. er muligt i princippet, men AFAIK er det aldrig blevet opnået i praksis – det ' er bestemt et tilfælde af at gøre tingene på den hårde måde.
- @ Steve314: I ' Jeg elsker at se det, hvis du nogensinde husker, hvor du fandt det!
- fandt det! Se kommentarerne til stackoverflow.com/questions/3317329/… med henvisning til Klein VM. En del af problemet med at finde det – spørgsmålet var lukket.
- BTW – Jeg ser ud til at være i stand til at starte mine kommentarer med @missingno – hvad giver?
- @ steve314: Efter at have vidnet svaret dette tråd er knyttet til, modtager jeg allerede en meddelelse om alle kommentarer. At udføre en @ -post i dette tilfælde ville være overflødig og er ikke tilladt af SE (don ' t spørg mig hvorfor dog). (Den virkelige årsag er dog, at mit nummer mangler)
Svar
Affaldssamling er fundamentalt uforenelig med en systemsprog, der bruges til at udvikle drivere til DMA-kompatibel hardware.
Det er fuldt ud muligt, at den eneste markør til et objekt vil blive gemt i et hardwareregister i noget perifert udstyr. Da affaldssamleren ikke vidste om dette, ville det tro, at objektet ikke kunne nås og samle det.
Dette argument holder dobbelt for komprimering af GC. Selvom du var omhyggelig med at opretholde referencer i hukommelsen til objekter, der bruges af hardware-periferiudstyr, da GC flyttede objektet, ville den ikke vide, hvordan man opdaterede markøren indeholdt i det perifere konfigurationsregister.
Så nu har du brug for en blanding af immobile DMA-buffere og GC-styrede objekter, hvilket betyder, at du har alle ulemperne ved begge.
Kommentarer
- Formentlig alle ulemperne ved begge, men færre forekomster af hver ulempe, og det samme for fordele. Der er tydeligvis kompleksitet i at have flere slags hukommelsesadministration at håndtere, men der kan også være kompleksitet undgås ved at vælge den rigtige hest til hvert kursus i din kode. Usandsynligt forestiller jeg mig, men der er ' et teoretisk hul der. Jeg ' har spekuleret i at blande GC og ikke-GC på samme sprog før, men ikke til enhedsdrivere – mere for at have en mest GC-applikation, men med nogle manuelt hukommelsesstyrede lave niveau datastrukturbiblioteker.
- @ Steve314: Ville ' ikke sige, at det at huske, hvilke objekter der skal frigøres manuelt, er så besværligt som at huske at frigøre alt? (Selvfølgelig kan smarte pointer hjælpe med begge, så ingen af dem er et stort problem) Og du har brug for forskellige puljer til manuelt styrede objekter vs indsamlede / komprimerbare objekter, da komprimering ikke ' t fungerer godt, når der er faste genstande spredt overalt. Så en masse ekstra kompleksitet for ingenting.
- Ikke hvis der ' er en klar opdeling mellem højkodekoden, som alle er GC, og lavt niveau kode, der vælger fra GC. Jeg udviklede hovedsageligt ideen, mens jeg kiggede på D for nogle år siden, hvilket giver dig mulighed for at fravælge GC, men ikke ' giver dig ikke mulighed for at tilmelde dig igen. Tag for eksempel et B + -træbibliotek . Beholderen som helhed skal være GC, men datastrukturen knuder sandsynligvis ikke – den ' er mere effektiv til kun at foretage en tilpasset scanning gennem bladknuderne end at gøre GC til en rekursiv søgning gennem grenknuderne. Denne scanning skal dog rapportere de indeholdte emner til GC.
- Pointen er, at ' er et indeholdt stykke funktionalitet. Behandling af B + -noder som speciel WRT-hukommelsesadministration er ikke anderledes end at behandle dem som specielle WRT der er B + -træ-noder. Det ' er et indkapslet bibliotek, og applikationskoden behøver ikke ' at vide, at GC-adfærd er blevet omgået / special-cased.Bortset fra at det i det mindste på det tidspunkt var umuligt i D – som jeg sagde, ingen måde at tilmelde sig og rapportere de indeholdte emner til GC som potentielle GC-rødder.
Svar
Fordi C & C ++ er relativt lavt sprog beregnet til generelle formål, selv for eksempel at køre på en 16-bit processor med 1 MB hukommelse i et indlejret system, som ikke havde råd til at spilde hukommelse med gc.
Kommentarer
- " Indbygget system "? På det tidspunkt, hvor C blev standardiseret (1989), var det nødvendigt at kunne håndtere pcer med 1 MB hukommelse.
- Jeg er enig, jeg citerede et mere aktuelt eksempel.
- 1 MB ??? Holy schmoley, hvem ville nogensinde have brug for så meget RAM? < / billGates >
Svar
Der er affaldssamlere i C ++ og C. Ikke sikker på, hvordan dette fungerer i C, men i C ++ kan du udnytte RTTI til dynamisk at opdage din objektgraf og bruge den til affaldsindsamling.
Efter min viden kan du ikke skrive Java uden affaldssamler. En lille søgning viste dette .
Nøgleforskellen mellem Java og C / C ++ er, at i C / C ++ er valget altid dit , hvorimod i Java ofte “efterlades uden muligheder efter design.
Kommentarer
- Og også at de dedikerede affaldssamlere er bedre implementeret, mere effektiv og passer bedre ind i sproget. 🙂
- Nej, du kan ' t bruge RTTI til dynamisk at opdage objektgrafen i C / C ++: Det ' er de almindelige gamle dataobjekter, der ødelægger alt. Der er simpelthen ingen RTTI-oplysninger gemt i et almindeligt gammelt dataobjekt, der gør det muligt for en affaldssamler at skelne mellem markører og ikke-pointere inden for objektet. Endnu værre, markører behøver ikke at være perfekt justeret på al hardware, så givet et 16 byte objekt er der 9 mulige placeringer, en 64 bit markør kan gemmes, hvoraf kun to ikke ' t overlapning.
Svar
Det er en afvejning mellem ydeevne og sikkerhed.
Der er ingen garanti for, at dit affald indsamles i Java, så det hænger muligvis rundt og bruger plads i lang tid, mens scanning efter ikke-henviste objekter (dvs. affald) også tager længere tid end eksplicit at slette eller frigøre et ubrugt objekt.
Fordelen er naturligvis, at man kan opbygge et sprog uden pegepunkter eller uden hukommelseslækager, så man er mere tilbøjelige til at producere korrekt kode.
Der kan være en lille “religiøs” kant til disse debatter nogle gange – advares!
Svar
Her er en liste over iboende problemer med GC, som gør det ubrugeligt i et systemsprog som C:
-
GC skal køre under niveauet for den kode, hvis objekter den administrerer. Der er simpelthen ikke et sådant niveau i en kerne.
-
En GC skal stoppe den administrerede kode fra tid til anden. Tænk nu over, hvad der ville ske, hvis det gjorde det med din kerne. Al behandling på din maskine stopper for eksempel en millisekund, mens GC scanner alle eksisterende hukommelsestildelinger. Dette ville dræbe alle forsøg på at oprette systemer, der fungerer under strenge krav i realtid.
-
En GC skal være i stand til at skelne mellem markører og ikke-henvisere. Det vil sige, det skal være i stand til at se på ethvert eksisterende hukommelsesobjekt og være i stand til at producere en liste over forskydninger, hvor dets pegepinde kan findes.
Denne opdagelse skal være perfekt: GC skal være i stand til at jagte alle de markeringer, den opdager. Hvis den afledte en falsk positiv, ville det sandsynligvis gå ned. Hvis det ikke lykkedes at opdage et falsk negativt, ville det sandsynligvis ødelægge et objekt, der stadig er i brug, nedbrudt den administrerede kode eller lydløst ødelægge dets data.
Dette kræver absolut, at typeoplysninger gemmes i hver enkelt objekt eksisterer. Både C og C ++ tillader imidlertid almindelige gamle dataobjekter, der ikke indeholder nogen typeoplysninger.
-
GC er en iboende langsom forretning. Programmører, der er socialiseret med Java måske ikke klar over dette, men programmer kan være størrelsesordener hurtigere, når de ikke implementeres i Java. Og en af de faktorer, der gør Java langsom, er GC. Dette er, hvad der udelukker, at GCed-sprog som Java bruges i supercomputing. Hvis din maskine koster en million om året i strømforbrug, vil du ikke betale selv 10% af det til affaldsindsamling.
C og C ++ er sprog, der er oprettet til at understøtte alle mulige brugssager. Og som du ser, er mange af disse brugssager udelukket af affaldsindsamling. For at understøtte disse brugssager kan C / C ++ ikke indsamles skrald.