Che cosa è esattamente il Garbage Collector in Java?

3

Penso di sapere generalmente cosa fa Garbage Collector in Java, ma è molto apprezzato, quindi ho pensato che forse mi manca qualcosa della sua funzionalità.

Quello che so è che il GC si occupa di cancellare dagli oggetti di memoria che non hanno alcun riferimento a loro, e quindi sono irraggiungibili dal programmatore.

Ad esempio, se all'interno di un loop creo costantemente new Object() , i precedenti verranno eliminati dal GC (correggimi se sbaglio).

Questo è molto utile per me come programmatore Java, e mi risparmia un sacco di mal di testa che presumo che i programmatori C ++ debbano affrontare: eliminare manualmente gli oggetti dalla memoria (di nuovo, correggimi se ho torto).

Questa funzione è fantastica, ma c'è qualcosa in più nel Garbage Collector? Mi manca qualcosa?

    
posta Aviv Cohn 01.03.2014 - 10:19
fonte

5 risposte

7

No, non manca nulla sulla Garbage Collection.

La garbage collection libera gli sviluppatori dai minimi dettagli di allocazione e de-allocazione della memoria.

Essere parte della piattaforma significa che c'è un'intera classe di problemi che Java non ha (e anche .NET e altri processi di raccolta dei rifiuti).

Ciò che potrebbe mancare è la quantità di problemi che hanno a che fare con allocazioni di memoria e de-allocazioni e i bug inerenti a non ottenerli correttamente;)

    
risposta data 01.03.2014 - 10:23
fonte
12

Per chi ha problemi di vista, ecco una parabola di Kieron Briggs :

Picture a big empty room with a big furnace/incinerator type thing at one end. Hanging form the roof are a number of ropes, called Threads. Attached to the various threads are little sparkly Objects, and those Objects can have other Object attached to them in turn by little rods called References. This creates a (hopefully) beautiful structure of Objects all attaches (either directly or indirectly) to a Thread. You can even have Objects which link to more than one Thread.

When an Object isn't needed any more, the Reference to it disappears. If that leaves the Object (or a whole collection of Objects) unattached to any Thread, it will fall down onto the floor and shatter. This gradually builds up a layer of broken objects lying around the floor. In a language like C, eventually the floor would become so full that there was no room for more Objects, and Bad Things would happen.

But in Java, we have a Garbage Collector. This is a little dude in overalls that climbs down a special Staff Only Thread, sweeps up all the broken Objects on the floor, and shovels them into the incinerator. You never know exactly when he's going to come along, but he's always there keeping an eye on the mess on the floor to make sure that it doesn't fill up too much...

  • descrizione più formale: algoritmo mark-and-sweep

    ...each object in memory has a flag (typically a single bit) reserved for garbage collection use only. This flag is always cleared, except during the collection cycle. The first stage of collection does a tree traversal of the entire 'root set', marking each object that is pointed to as being 'in-use'. All objects that those objects point to, and so on, are marked as well, so that every object that is ultimately pointed to from the root set is marked. Finally, all memory is scanned from start to finish, examining all free or used blocks; those with the in-use flag still cleared are not reachable by any program or data, and their memory is freed. (For objects which are marked in-use, the in-use flag is cleared again, preparing for the next cycle.)

    
risposta data 03.03.2014 - 07:39
fonte
3

Non ti manca nulla. Tuttavia, vorrei sottolineare qualcosa che non penso che nessuna delle altre risposte abbia affrontato chiaramente. La raccolta dei rifiuti riguarda innanzitutto la correttezza e la sicurezza del programma; la convenienza è secondaria (sebbene sia molto conveniente).

Se il programmatore gestisce la memoria manualmente, commettere un errore significa corrompere lo stato del programma. Il programma continua ma l'esecuzione non è più disponibile e non ha più alcun significato . Potrebbe fallire catastroficamente subito, ma probabilmente continuerà ad andare in un modo apparentemente corretto ma molto sottilmente sbagliato, probabilmente per giorni o settimane prima che qualcuno si accorga del problema. Ancora peggio è che i bug di memoria potrebbero essere sfruttati dagli aggressori. Se il programma buggy viene eseguito con i privilegi di amministratore e il bug consente a un utente malintenzionato di eseguire codice arbitrario, il potenziale di danno è quasi illimitato. Questo tipo di bug è molto difficile da rilevare e impossibile da evitare; prima o poi introdurremo un bug di memoria perché siamo tutti umani. Un linguaggio che esclude completamente la gestione manuale della memoria è garantito privo di questo tipo di bug (anche se i bug di memoria non sono sicuramente l'unico modo per introdurre una vulnerabilità di sicurezza.)

La mancanza di garbage collection preclude generalmente strutture di oggetti complicate. Per la maggior parte sei limitato alla creazione di oggetti che esistono sempre o che hanno un singolo proprietario che è responsabile della loro eliminazione. Ciò esclude, ad esempio, strutture dati persistenti , perché qualsiasi nodo dato potrebbe essere condiviso da molti oggetti e non esiste un modo affidabile di gestirlo. L'utilizzo di puntatori intelligenti con il conteggio dei riferimenti non è una soluzione: le loro prestazioni sono errate e i riferimenti cylic (due oggetti che si indicano l'un l'altro) non verranno liberati. Puoi introdurre riferimenti deboli per evitare il secondo problema, ma ora hai reso la gestione manuale della memoria ancora più difficile da ottenere (e le prestazioni sono ancora negative). La garbage collection consente a queste complicate strutture di dati di essere ripulite correttamente e in modo efficiente.

Ironicamente, la mancanza di strutture di dati persistenti rende il programma più difficile da ragionare, perché le modifiche alla struttura dei dati sono distruttive e ora devi stare molto attento a chi ha dei riferimenti e chi sta apportando modifiche ad esso. Quindi, oltre ai bug di memoria, devi preoccuparti anche di altri bug di stato / aliasing.

    
risposta data 03.03.2014 - 14:09
fonte
0

Un'analogia simile alla risposta di gnat è immaginare qualcuno seduto a una scrivania in un ufficio cartaceo. La persona esegue le attività utilizzando documenti cartacei (oggetti) e ha bisogno di avere questi pezzetti di carta sulla scrivania. Quando hanno finito e non hanno più bisogno di fare riferimento a un documento, lo gettano nel cestino.

La scrivania e il cestino hanno una capacità finita (memoria). Il GC è il custode che arriva occasionalmente e svuota il cestino in modo che non venga superata la capacità *.

* Naturalmente puoi sempre esaurire la memoria mettendo troppi documenti sulla tua scrivania. Non c'è nulla che il bidello possa fare per questo.

    
risposta data 03.03.2014 - 11:51
fonte
0

C'è un'altra cosa che puoi fare con GC oltre a scaricare semplicemente la tua gestione della memoria: riferimenti deboli , che potrebbe essere utilizzato per scaricare la gestione delle cache su GC.

I tuoi oggetti deboli sono raggiungibili e possono ancora essere utilizzati a un certo punto, ma stai istruendo GC che è giusto sbarazzarsi di loro in qualsiasi momento, e non ti importa di perderli.

    
risposta data 03.03.2014 - 12:05
fonte

Leggi altre domande sui tag