Commenti
- ' abbiamo un modulo per lo sviluppo di iPhone questo semestre. Dopo aver codificato app per Android per 2 anni, questa domanda ha colpito la maggior parte della classe piuttosto duramente. Solo ora vediamo quante ore ci ha effettivamente risparmiato Java per non dover rintracciare brutti errori di gestione della memoria e non dover scrivere codice boilerplate.
- @NullUserException, dato che non ' t specificare un modo per recuperare la memoria che più o meno implica un GC.
- @ bizso09: Hai già guardato ARC? Non cè bisogno di GC lento / grasso / non deterministico quando ' hai il supporto di sistema per il conteggio dei riferimenti: developer.apple. com / technologies / ios5
- Le risposte a questa bella domanda sono piene di stronzate religiose.
- In C e C ++ è possibile prendere un puntatore, lanciarlo a int e aggiungere un numero ad esso. Successivamente sottrarre il numero dallint e restituire il risultato a un puntatore. Otterrai lo stesso puntatore di prima. Buona fortuna nellimplementare un GC che NON raccoglie quella memoria mentre il suo indirizzo è memorizzato solo nella variabile che ha anche un altro valore. So che lesempio è sciocco, ma un elenco collegato XOR utilizza qualcosa di simile. Lo pubblicherei come risposta, ma la domanda è chiusa.
Risposta
La raccolta dei rifiuti richiede strutture di dati per monitoraggio delle allocazioni e / o conteggio dei riferimenti. Questi creano overhead in memoria, prestazioni e complessità del linguaggio. Il C ++ è progettato per essere “vicino al metallo”, in altre parole, prende il lato delle prestazioni più elevate del compromesso rispetto alle funzionalità di convenienza. Altre lingue fanno questo compromesso in modo diverso. Questa è una delle considerazioni nella scelta di una lingua, quale enfasi preferisci.
Detto questo, ci sono molti schemi per il conteggio dei riferimenti in C ++ che sono abbastanza leggeri e performanti, ma sono nelle librerie, sia commerciali che open source, piuttosto che parte del linguaggio stesso. Il conteggio dei riferimenti per gestire la durata degli oggetti non è la stessa cosa della garbage collection, ma risolve molti degli stessi tipi di problemi e si adatta meglio allapproccio di base di C ++.
Commenti
- Un problema secondario è che il GC non è deterministico. Loggetto può o non può essere ancora in memoria molto tempo dopo che il programma è stato " eliminato " it. Refcount lifecycles sono deterministici, quando lultimo riferimento viene eliminato, la memoria viene eliminata. Ciò ha implicazioni non solo per lefficienza della memoria, ma anche per il debug. Un errore di programmazione comune è loggetto " zombie ", memoria di riferimento che è stata teoricamente eliminata. È molto più probabile che GC mascherino questo effetto e produca bug che sono intermittenti ed estremamente difficili da rintracciare.
- – il moderno gc ' non tiene traccia delle allocazioni o del conteggio dei riferimenti. Creano un grafico da eve rything attualmente sullo stack e solo condensare e cancellare tutto il resto (semplificato), e GC normalmente si traduce in una ridotta complessità del linguaggio. Anche il vantaggio in termini di prestazioni è discutibile.
- Ehm, @kylben, il punto centrale dellavere un GC automatico inserito nel linguaggio è che diventa impossibile fare riferimento a oggetti zombi, perché il GC libera solo oggetti a cui è impossibile fare riferimento! Ottieni il tipo di bug difficili da rintracciare di cui ' stai parlando quando commetti errori con la gestione manuale della memoria.
- -1, GC non conta Riferimenti. Inoltre, a seconda dellutilizzo della memoria e dello schema di allocazione, un GC può essere più veloce (con un sovraccarico nellutilizzo della memoria). Quindi anche largomento sulla performance è fallace. Solo la vicinanza al metallo è un punto valido in realtà.
- Né Java né C # usano il conteggio dei riferimenti: gli schemi GC basati sul conteggio dei riferimenti sono piuttosto primitivi in confronto e hanno prestazioni molto peggiori dei moderni garbage collector (principalmente perché è necessario eseguire scritture in memoria per alterare il conteggio dei riferimenti ogni volta che si copia un riferimento!)
Answer
A rigor di termini, non esiste alcuna gestione della memoria nel linguaggio C. malloc () e free () non sono parole chiave nella lingua, ma solo funzioni chiamate da una libreria.Questa distinzione può essere pedante ora, perché malloc () e free () fanno parte della libreria standard del C e sarà fornita da qualsiasi implementazione conforme allo standard di C, ma questo non era sempre vero in passato.
Perché vorresti un linguaggio senza standard per la gestione della memoria? Questo risale alle origini di C come “assembly portatile”. Esistono molti casi di hardware e algoritmi che possono beneficiare o addirittura richiedere tecniche di gestione della memoria specializzate. Per quanto ne so, non cè modo di disabilitare completamente la gestione della memoria nativa di Java e sostituirla con la tua. Questo semplicemente non è accettabile in alcune situazioni ad alte prestazioni / risorse minime. C fornisce una flessibilità quasi completa per scegliere esattamente quale infrastruttura il vostro programma utilizzerà. Il prezzo pagato è che il linguaggio C fornisce pochissimo aiuto per scrivere codice corretto e privo di bug.
Commenti
- +1 per la risposta complessivamente buona, ma anche soprattutto per " Il prezzo pagato è che il linguaggio C fornisce pochissimo aiuto per scrivere codice corretto e privo di bug "
- C dispone della gestione della memoria, ma funziona, quindi le persone lo notano a malapena. La memoria statica, i registri e la ' stack. Fino a quando non inizi ad allocare fuori dallheap, ' stai bene ed è dandy. ' è lallocazione dellheap che rovina le cose . Come per Java, tutti possono scrivere il proprio runtime Java: ' cè molto da scegliere, incluso quello che potrebbe essere chiamato " Sistema ' s Java ". .NET può fare praticamente tutto ciò che può fare C – è solo in ritardo rispetto alle capacità native di C ++ ' (ad esempio le classi sono gestite solo in .NET). Naturalmente, hai anche C ++. NET, che ha tutto ciò che fa C ++ e tutto ciò che fa .NET.
- @Luaan I ' dico che ' una definizione molto generosa di " gestione della memoria " " Finché non inizi ad allocare fuori dallheap, ' stai bene. È ' lallocazione dellheap che rovina le cose ", che ' è come dire unauto è un ottimo aeroplano, semplicemente ' non è in grado di volare.
- @ CharlesE.Grant Beh, un linguaggio puramente funzionale può fare tutto con quello tipo di gestione della memoria. Solo perché lallocazione dellheap è un buon compromesso in alcuni casi duso non ' significa che ' è il punto di riferimento per tutte le lingue / runtime . ' non è che la gestione della memoria smetta di essere " gestione della memoria " solo perché ' è semplice, diretto, nascosto dietro le quinte. Progettare lallocazione della memoria statica è ancora una gestione della memoria, così come un buon uso dello stack e di qualsiasi altra cosa a disposizione.
- " qualsiasi implementazione conforme agli standard " non è vero, solo per limplementazione dellambiente host conforme agli standard. Alcune piattaforme / librerie standard, la maggior parte per microcontrollori incorporati a 8 o 16 bit, non forniscono
malloc()
ofree()
. (gli esempi sono i compilatori MLAP per PIC)
Answer
La vera risposta è che lunico modo per fare un meccanismo di garbage collection sicuro ed efficiente consiste nellavere supporto a livello di lingua per i riferimenti opachi. (O, al contrario, una mancanza di supporto a livello di linguaggio per la manipolazione diretta della memoria.)
Java e C # possono farlo perché hanno tipi di riferimento speciali che non possono essere manipolati. Questo dà al runtime la libertà di fare cose come spostare gli oggetti allocati in memoria , che è fondamentale per unimplementazione GC ad alte prestazioni .
Per la cronaca, nessuna implementazione GC moderna utilizza il conteggio dei riferimenti , quindi è completamente rosso aringa. I GC moderni utilizzano la raccolta generazionale, in cui le nuove allocazioni vengono trattate essenzialmente allo stesso modo in cui le allocazioni di stack sono in un linguaggio come C ++, quindi periodicamente tutti gli oggetti appena allocati che sono ancora vivi vengono spostati in uno spazio “sopravvissuto” separato e unintera generazione degli oggetti viene deallocato contemporaneamente.
Questo approccio ha pro e contro: il vantaggio è che le allocazioni di heap in un linguaggio che supporta GC sono veloci quanto le allocazioni di stack in un linguaggio che non supporta GC e lo svantaggio è che gli oggetti che devono essere puliti prima di essere distrutti richiedono un meccanismo separato (ad es. C #” s using
parola chiave) oppure il loro codice di pulizia viene eseguito in modo non deterministico.
Si noti che una chiave per un GC ad alte prestazioni è che deve esserci il supporto del linguaggio per una classe speciale di riferimenti. Il C non ha questo supporto per il linguaggio e non lo farà mai; poiché il C ++ ha loverloading degli operatori, potrebbe emulare un tipo di puntatore GC “d, sebbene dovrebbe essere fatto con attenzione. Infatti, quando Microsoft ha inventato il proprio dialetto di C ++ che sarebbe stato eseguito sotto CLR (il runtime .NET), ha dovuto inventare una nuova sintassi per i “riferimenti in stile C #” (ad esempio Foo^
) per distinguerli dai “riferimenti in stile C ++” (ad es. Foo&
).
Ciò che ha il C ++ e ciò che viene usato regolarmente dai programmatori C ++ è puntatori intelligenti , che in realtà sono solo un meccanismo di conteggio dei riferimenti. Non considererei il conteggio dei riferimenti un GC “vero”, ma fornisce molti degli stessi vantaggi, al costo di prestazioni più lente rispetto alla gestione manuale della memoria o al vero GC, ma con il vantaggio della distruzione deterministica.
Alla fine della giornata, la risposta si riduce a una caratteristica di progettazione del linguaggio. C ha fatto una scelta, C ++ ha fatto una scelta che gli ha permesso di essere retrocompatibile con C pur fornendo alternative abbastanza buone per la maggior parte degli scopi, e Java e C # hanno fatto una scelta diversa che è incompatibile con C ma è anche abbastanza buona per la maggior parte degli scopi. Sfortunatamente, non esiste un proiettile dargento, ma avere familiarità con le diverse scelte disponibili ti aiuterà a scegliere quello corretto per qualunque programma tu stia attualmente cercando di creare.
Commenti
- Questa è la risposta effettiva alla domanda
- Per la parte c ++, al giorno doggi dovresti guardare std :: unique_ptr e std :: move 🙂
- nessun implem GC moderno entation utilizza il conteggio dei riferimenti : cPython utilizza sia il conteggio dei riferimenti e la raccolta automatica .
- @ Mike76: dal lato dellallocazione, un allocatore GC funzionerà alla stessa velocità dellallocazione dello stack e il GC può deallocare migliaia di oggetti contemporaneamente. Indipendentemente da ciò che fai con unimplementazione del conteggio ref, lallocazione e la deallocazione non saranno mai più veloci di
malloc
efree
. Quindi sì, un GC può essere sostanzialmente più veloce. (Tieni presente che ho detto che " può essere " – ovviamente le prestazioni esatte di ogni programma sono influenzate da molti fattori.) - nessuna implementazione GC moderna utilizza il conteggio dei riferimenti Swift utilizza il conteggio automatico dei riferimenti.
Risposta
Perché, quando si usa la potenza di C ++, non ce nè bisogno.
Herb Sutter:” Non ho “scritto” cancella da anni. ”
vedi Scrivere codice C ++ moderno: come si è evoluto C ++ nel corso degli anni 21:10
Potrebbe sorprendere molti programmatori C ++ esperti.
Commenti
- Interessante. Il mio materiale di lettura per oggi.
- Bah, un video. Ma comunque già interessante.
- video interessante. 21 minuti e 55 minuti sono stati i momenti migliori. Peccato che le chiamate WinRT sembrassero ancora essere C ++ / CLI bumpf.
- @ dan04: Questo ' è vero. Ma poi, se scrivi in C, ottieni quello che chiedi.
- Gestire i puntatori intelligenti non è più impegnativo che assicurarti di non ' t avere riferimenti non necessari in un ambiente raccolto dalla spazzatura. Dato che GC ' non ti legge nel pensiero, ' non è neanche magico.
Risposta
“Tutto” è un garbage collector è un processo che viene eseguito periodicamente controllando per vedere se ci sono oggetti non referenziati in memoria e se ce ne sono li elimina. (Sì, lo so che questa è una grossolana semplificazione). Questa non è una proprietà del linguaggio, ma del framework.
Ci sono garbage collector scritti per C e C ++ – questo per esempio .
Uno dei motivi per cui non è stato “t” aggiunto “alla lingua potrebbe essere lenorme volume di codice esistente che non lo userebbe mai poiché usano il proprio codice per la gestione della memoria. Un altro motivo potrebbe essere che i tipi di applicazioni scritte in C e C ++ non necessitano delloverhead associato a un processo di garbage collection.
Commenti
- Ma i programmi futuri scritto inizierebbe ad usare il garbage collector, no?
- Sebbene la garbage collection sia teoricamente indipendente da qualsiasi linguaggio di programmazione, è piuttosto difficile scrivere un GC utile per C / C ++ e persino impossibile crearne uno infallibile (almeno altrettanto infallibile di Java ' s): il motivo per cui Java può farcela è perché viene eseguito in un ambiente virtualizzato controllato. Al contrario, il linguaggio Java è progettato per GC e ' avrai difficoltà a scrivere un compilatore Java che non ' fai GC .
- @tdammers: Sono daccordo che la garbage collection debba essere supportata dalla lingua per essere possibile. Tuttavia, il punto principale non è la virtualizzazione e lambiente controllato, ma la tipizzazione rigorosa. C e C ++ sono tipizzati debolmente, quindi consentono cose come memorizzare il puntatore in una variabile intera, ricostruire i puntatori dagli offset e cose simili che impediscono al raccoglitore di essere in grado di dire in modo affidabile ciò che è raggiungibile (C ++ 11 proibisce al successivo di consentire almeno collezionisti conservatori). In Java sai sempre cosè un riferimento, quindi puoi raccoglierlo con precisione, anche se compilato in nativo.
- @Thorbj ø rnRavnAndersen: Posso scrivere un programma C valido che memorizza i puntatori in modo tale che nessun garbage collector possa mai trovarli. Se poi agganci un garbage collector a
malloc
efree
, interromperesti il mio programma corretto. - @Thorbj ø rnRavnAndersen: No, non ' chiamare
free
fino a quando non avessi finito . Ma il tuo garbage collector proposto che ' non libera la memoria finché non chiamo esplicitamentefree
non è ' un garbage collector.
Answer
C è stato progettato in unera in cui la garbage collection era a malapena un opzione. Era anche pensato per usi in cui la raccolta dei rifiuti non funzionava generalmente: ambienti bare metal in tempo reale con memoria minima e supporto minimo per il runtime. Ricorda che C era il linguaggio di implementazione per il primo unix, che girava su un pdp-11 con 64 * K * byte di memoria. Il C ++ era originariamente unestensione di C: la scelta era già stata fatta ed è molto difficile innestare la garbage collection in un linguaggio esistente. È il genere di cose che devono essere costruite dal piano terra.
Risposta
Non ho le virgolette esatte ma sia Bjarne che Herb Sutter dicono qualcosa del genere:
C ++ non ha bisogno di un garbage collector, perché non ha spazzatura.
Nella moderna C ++ usi puntatori intelligenti e quindi non hai spazzatura.
Commenti
- cosa sono i puntatori intelligenti?
- se fosse quello semplice, nessuno avrebbe implementato alcun GC.
- @deadalnix: Giusto, perché nessuno implementa mai qualcosa di eccessivamente complicato, lento, gonfio o non necessario. Tutto il software è sempre efficiente al 100%, giusto?
- @deadalnix – Lapproccio C ++ alla gestione della memoria è più recente dei garbage collector. RAII è stato inventato da Bjarne Stroustrup per C ++. La pulizia del distruttore è unidea più vecchia, ma le regole per garantire la sicurezza dalle eccezioni sono fondamentali. Non ' non so esattamente quando lidea stessa è stata descritta per la prima volta, ma il primo standard C ++ è stato finalizzato nel 1998 e Stroustrups " Design e Evolution of C ++ " non è stato ' t pubblicato fino al 1994 e le eccezioni erano unaggiunta relativamente recente a C ++, dopo la pubblicazione del " Manuale di riferimento C ++ con annotazioni " nel 1990, credo. GC è stato inventato nel 1959 per Lisp.
- @deadalnix – sei consapevole del fatto che almeno una Java VM utilizzava un GC conteggio dei riferimenti che poteva (quasi) essere implementato utilizzando RAII in stile C ++ utilizzando una classe puntatore intelligente – precisamente perché era più efficiente per il codice multithread rispetto alle VM esistenti? Vedere www.research.ibm.com/people/d/dfb/papers/Bacon01Concurrent.pdf. Uno dei motivi per cui ' non viene visualizzato in C ++ in pratica è la solita raccolta GC: può raccogliere cicli, ma ' scegliere un ordine sicuro del distruttore in presenza di cicli, e quindi non può garantire una pulizia affidabile del distruttore.
Risposta
Tu chiedi perché questi linguaggi non sono stati aggiornati per includere un garbage collector opzionale.
Il problema con la garbage collection opzionale è che non puoi mescolare codice che usa i diversi modelli. Cioè, se scrivo codice che presume che tu stia usando un garbage collector non puoi usarlo nel tuo programma che ha la garbage collection disattivata. Se lo fai, colerà ovunque.
Risposta
Ci sono vari problemi, tra cui …
- Sebbene GC sia stato inventato prima del C ++, e forse prima del C, sia C che C ++ furono implementati prima che i GC fossero ampiamente accettati come pratici.
- Non puoi implementare facilmente un Linguaggio e piattaforma GC senza un linguaggio sottostante non GC.
- Sebbene GC sia dimostrabilmente più efficiente di non GC per il codice di applicazioni tipiche sviluppate in scale temporali tipiche ecc., Ci sono problemi in cui uno sforzo di sviluppo maggiore è un buon affare -off e la gestione della memoria specializzata supereranno le prestazioni di un GC generico. Inoltre, il C ++ è tipicamente più efficiente della maggior parte dei linguaggi GC anche senza alcuno sforzo di sviluppo aggiuntivo.
- GC non è universalmente più sicuro di RAII in stile C ++ . RAII consente la pulizia automatica di risorse diverse dalla memoria, fondamentalmente perché supporta distruttori affidabili e tempestivi. Questi non possono essere combinati con i metodi GC convenzionali a causa di problemi con i cicli di riferimento.
- I linguaggi GC hanno le loro caratteristiche tipi di memoria perdite, in particolare relative alla memoria che non verrà mai più utilizzata, ma dove esistevano riferimenti esistenti che non sono mai stati annullati o sovrascritti. La necessità di farlo esplicitamente non è diversa in linea di principio dalla necessità di
delete
ofree
esplicitamente. Lapproccio GC ha ancora un vantaggio – nessun riferimento penzolante – e lanalisi statica può catturare alcuni casi, ma ancora una volta, non esiste una soluzione perfetta per tutti i casi.
Fondamentalmente, in parte ” Riguarda letà delle lingue, ma ci sarà comunque sempre un posto per le lingue non GC, anche se è un posto un po di nicchia. E seriamente, in C ++, la mancanza di GC non è “un grosso problema: la tua memoria è gestita in modo diverso, ma non è non gestita.
Il C ++ gestito da Microsoft ha almeno una certa capacità di combinare GC e non GC nella stessa applicazione, consentendo un mix-and-match dei vantaggi di ciascuno, ma non ho lesperienza per dire quanto bene funzioni nella pratica.
Link rep-whoring a risposte correlate mio …
- 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
Risposta
Riesci a immaginare di scrivere un gestore di dispositivi in una lingua con garbage collection? Quanti bit potrebbero arrivare al mentre il GC era in esecuzione?
O un sistema operativo? Come hai potuto avviare la garbage collection in esecuzione prima ancora di avviare il kernel?
C è progettato per un livello basso vicino alle attività hardware. Il problema? è un linguaggio così carino da essere una buona scelta anche per molte attività di livello superiore. Gli zar del linguaggio sono consapevoli di questi usi ma devono supportare i requisiti dei driver di dispositivo, del codice incorporato e dei sistemi operativi come priorità.
Commenti
- C va bene per un alto livello? Ho sbuffato il mio drink su tutta la tastiera.
- Beh, ha detto " molte attività di livello superiore ". Potrebbe contare i troll (uno, due, molti …). E non ha ' in realtà detto più in alto di cosa. Scherzi a parte, però, è ' vero – levidenza è che molti progetti significativi di livello superiore sono stati sviluppati con successo in C. Potrebbero esserci scelte migliori ora per molti di questi progetti, ma un progetto funzionante è una prova più forte della speculazione su ciò che avrebbe potuto essere.
- Ci sono ' alcuni sistemi operativi gestiti, e funzionano piuttosto bene. In effetti, quando si esegue la gestione dellintero sistema, il calo delle prestazioni derivante dallutilizzo di codice gestito diminuisce ancora di più, fino ad essere più veloce rispetto al codice non gestito in scenari di vita reale. Ovviamente, questi sono tutti " sistema operativo di ricerca " – lì ' praticamente no modo per renderli compatibili con il codice esistente non gestito oltre a creare un sistema operativo non gestito completamente virtualizzato allinterno del sistema operativo gestito. Microsoft ha suggerito a un certo punto che potrebbero sostituire Windows Server con uno di questi, tuttavia, poiché sempre più codice server viene scritto su .NET.
Risposta
La risposta breve e noiosa a questa domanda è che ci deve essere un linguaggio non-garbage collection là fuori per le persone che scrivono i garbage collector. Non è concettualmente facile avere un linguaggio che allo stesso tempo consenta un controllo molto preciso sul layout della memoria e ha un GC in esecuzione sopra.
Laltra domanda è perché C e C ++ non hanno i garbage collector.Beh, so che C ++ ne ha un paio in giro, ma non sono molto popolari perché sono costretti a gestire un linguaggio che non è stato progettato per essere GC-ed in primo luogo, e le persone che usano ancora C ++ in questa età non è proprio il tipo a cui manca un GC.
Inoltre, invece di aggiungere GC a un vecchio linguaggio non GC, è effettivamente più facile creare un nuovo linguaggio che abbia la maggior parte delle stessa sintassi pur supportando un GC. Java e C # ne sono buoni esempi.
Commenti
- Da qualche parte su programmers.se o SO, ci ' sa che qualcuno mi ha fatto notare che qualcuno stava lavorando su una cosa raccolta da dati obsoleti con avvio automatico – IIRC fondamentalmente implementa la VM utilizzando un linguaggio GC, con un sottoinsieme bootstrap utilizzato per implementare il GC stesso . Ho dimenticato il nome. Quando lho esaminato, si è scoperto che ' praticamente non sono mai riusciti a passare dal sottoinsieme senza GC al livello GC funzionante. è possibile in linea di principio, ma AFAIK non è mai stato raggiunto nella pratica: ' è certamente un caso di fare le cose nel modo più duro.
- @ Steve314: I ' mi piacerebbe vederlo, se mai ti ricordi dove lhai trovato!
- lho trovato! Vedi i commenti a stackoverflow.com/questions/3317329/… che fanno riferimento alla VM Klein. Parte del problema nel trovarlo: la domanda è stata chiusa.
- BTW – Non riesco a iniziare i miei commenti con @missingno – cosa succede?
- @ steve314: Avendo scritto la risposta questa thread è allegato a, ricevo già una notifica per tutti i commenti. Fare un @ -post in questo caso sarebbe ridondante e non è consentito da SE (non ' non chiedermi perché però). (La vera causa però è perché manca il mio numero)
Risposta
La raccolta dei rifiuti è fondamentalmente incompatibile con un linguaggio di sistema utilizzato per lo sviluppo di driver per hardware compatibile con DMA.
È del tutto possibile che lunico puntatore a un oggetto venga memorizzato in un registro hardware in qualche periferica. Dal momento che il garbage collector non lo saprebbe a questo proposito, penserebbe che loggetto sia irraggiungibile e lo raccoglierà.
Questo argomento vale il doppio per la compattazione di GC. Anche se fossi attento a mantenere i riferimenti in memoria agli oggetti usati dalle periferiche hardware, quando il GC ha riposizionato loggetto, non saprebbe come aggiornare il puntatore contenuto nel registro di configurazione della periferica.
Quindi ora avresti bisogno di una combinazione di buffer DMA immobili e oggetti gestiti da GC, il che significa che hai tutti gli svantaggi di entrambi.
Commenti
- Probabilmente tutti gli svantaggi di entrambi, ma meno casi di ciascuno svantaggio e lo stesso per i vantaggi. Chiaramente cè complessità nellavere più tipi di gestione della memoria da affrontare, ma può anche essere evitata la complessità scegliendo il cavallo giusto per ogni corso allinterno del codice. Improbabile, immagino, ma ' cè una lacuna teorica. ' ho già ipotizzato di combinare GC e non GC nella stessa lingua, ma non per i driver di dispositivo – più per avere unapplicazione principalmente GC, ma con un po di memoria gestita manualmente librerie di strutture dati di livello.
- @ Steve314: ' non diresti che ricordare quali oggetti devono essere liberati manualmente è oneroso come ricordarsi di liberare tutto? (Ovviamente, i puntatori intelligenti possono aiutare con entrambi, quindi nessuno dei due è un grosso problema) E hai bisogno di pool diversi per oggetti gestiti manualmente rispetto a oggetti raccolti / comprimibili, poiché la compattazione non ' t funzionano bene quando ci sono oggetti fissi sparsi ovunque. Quindi molta complessità in più per niente.
- No se ' cè una netta divisione tra il codice di alto livello che è tutto GC e il codice di basso livello codice che disattiva GC. Ho sviluppato lidea principalmente mentre guardavo D alcuni anni fa, che ti consente di disattivare GC ma ' t ti consente di riattivare. Prendi ad esempio una libreria ad albero B + . Il contenitore nel suo insieme dovrebbe essere GC, ma i nodi della struttura dati probabilmente no: ' è più efficiente eseguire una scansione personalizzata solo attraverso i nodi foglia piuttosto che fare in modo che il GC esegua ricerca ricorsiva attraverso i nodi del ramo. Tuttavia, quella scansione deve riportare gli elementi contenuti al GC.
- Il punto è che ' è una funzionalità contenuta. Trattare i nodi dellalbero B + come una speciale gestione della memoria WRT non è diverso dal trattarli come nodi WRT essendo B + speciali. ' è una libreria incapsulata e il codice dellapplicazione ' non deve sapere che il comportamento del GC è stato ignorato / in casi speciali.Tranne che, almeno al momento, era impossibile in D – come ho detto, non cè modo di riattivare e segnalare gli elementi contenuti al GC come potenziali radici GC.
Risposta
Perché, C & C ++ sono linguaggi di livello relativamente basso pensati per scopi generali, anche, ad esempio, per funzionare su un processore a 16 bit con 1 MB di memoria in un sistema integrato, che non poteva permettersi di sprecare memoria con gc.
Commenti
- " Sistema integrato "? Allepoca in cui C fu standardizzato (1989), doveva essere in grado di gestire PC con 1 MB di memoria.
- Sono daccordo, stavo citando un esempio più attuale.
- 1 MB ??? Santo schmoley, chi avrebbe mai bisogno di così tanta RAM? < / billGates >
Risposta
Ci sono garbage collector in C ++ e C. Non sono sicuro di come funzioni in C, ma in C ++ puoi sfruttare RTTI per scoprire dinamicamente il tuo grafico a oggetti e usarlo per la garbage collection.
Per quanto ne so, non puoi scrivere Java senza un garbage collector. Una piccola ricerca ha portato a questo .
La differenza fondamentale tra Java e C / C ++ è che in C / C ++ la scelta è sempre tua , mentre in Java “sei spesso lasciato senza opzioni di progettazione.
Commenti
- E anche che i garbage collector dedicati sono implementati meglio, più efficienti e adattarsi meglio alla lingua. 🙂
- No, puoi ' t utilizzare RTTI per scoprire dinamicamente loggetto grafico in C / C ++: It ' sono i semplici vecchi oggetti di dati che rovinano tutto Semplicemente non ci sono informazioni RTTI memorizzate in un semplice vecchio oggetto di dati che consentirebbero a un garbage collector di distinguere tra puntatori e non puntatori allinterno di quelloggetto. Ancora peggio, non è necessario che i puntatori siano perfettamente allineati su tutto lhardware, quindi, dato un oggetto a 16 byte, ci sono 9 possibili posizioni in cui è possibile memorizzare un puntatore a 64 bit, solo due delle quali don ' t si sovrappongono.
Risposta
È “un compromesso tra prestazioni e sicurezza.
Non vi è alcuna garanzia che la spazzatura venga raccolta in Java, quindi può rimanere in giro a utilizzare lo spazio per molto tempo, mentre la scansione di oggetti non referenziati (cioè spazzatura) richiede anche più tempo che eliminare o liberare esplicitamente un oggetto inutilizzato.
Il vantaggio è, ovviamente, che si può costruire un linguaggio senza puntatori o senza perdite di memoria, quindi è più probabile che si produca un codice corretto.
A volte può esserci un leggero vantaggio “religioso” in questi dibattiti – state attenti!
Risposta
Ecco un elenco di problemi intrinseci di GC, che lo rendono inutilizzabile in un linguaggio di sistema come C:
-
Il GC deve essere eseguito al di sotto del livello del codice di cui gestisce gli oggetti. Semplicemente non esiste un tale livello in un kernel.
-
Un GC deve interrompere il codice gestito di tanto in tanto. Ora pensa a cosa accadrebbe se lo facesse al tuo kernel. Tutta lelaborazione sulla macchina si interromperà, ad esempio, per un millisecondo, mentre il GC analizza tutte le allocazioni di memoria esistenti. Questo ucciderebbe tutti i tentativi di creare sistemi che operino sotto rigorosi requisiti in tempo reale.
-
Un GC deve essere in grado di distinguere tra puntatori e non puntatori. Cioè, deve essere in grado di guardare ogni oggetto di memoria esistente ed essere in grado di produrre un elenco di offset in cui possono essere trovati i suoi puntatori.
Questa scoperta deve essere perfetta: il GC deve essere in grado di per inseguire tutti i puntatori che scopre. Se dereferenziasse un falso positivo, probabilmente andrebbe in crash. Se non riuscisse a scoprire un falso negativo, probabilmente distruggerebbe un oggetto ancora in uso, mandando in crash il codice gestito o danneggiando silenziosamente i suoi dati.
Ciò richiede assolutamente che le informazioni sul tipo siano memorizzate in ogni singolo oggetto esistente. Tuttavia, sia C che C ++ consentono semplici oggetti dati vecchi che non contengono informazioni sul tipo.
-
GC è unattività intrinsecamente lenta. I programmatori che sono stati socializzati con Java potrebbe non rendersene conto, ma i programmi possono essere di ordini di grandezza più veloci quando non sono implementati in Java. E uno dei fattori che rallentano Java è GC. Questo è ciò che impedisce ai linguaggi GCed come Java di essere utilizzati nel supercalcolo. Se la tua macchina costa un milione allanno in consumo di energia, non vuoi pagare nemmeno il 10% di quello per la raccolta dei rifiuti.
C e C ++ sono linguaggi creati per supportare tutti i possibili casi duso. E, come puoi vedere, molti di questi casi duso sono preclusi dalla garbage collection. Quindi, per supportare questi casi duso, C / C ++ non può essere sottoposto a garbage collection.