Cos'è il garbage collector in Java?


103

Sono nuovo in Java e confuso sul garbage collector in Java. Cosa fa effettivamente e quando entra in azione. Descrivi alcune delle proprietà del garbage collector in Java.


2
possibile duplicato di Garbage Collection
Ian Ringrose

10
A volte è meglio leggere il capitolo di un buon libro aspettarsi di capire un argomento complesso dalla risposta a una domanda.
Ian Ringrose

4
@Ian È una domanda simile, ma non un duplicato. E quella domanda puzza di compiti a casa.
NullUserException

Risposte:


119

Il garbage collector è un programma che viene eseguito sulla Java Virtual Machine che elimina gli oggetti che non vengono più utilizzati da un'applicazione Java. È una forma di gestione automatica della memoria .

Quando una tipica applicazione Java è in esecuzione, è la creazione di nuovi oggetti, come Strings e Files, ma dopo un certo tempo, quegli oggetti non vengono più utilizzati. Ad esempio, dai un'occhiata al seguente codice:

for (File f : files) {
    String s = f.getName();
}

Nel codice sopra, String sviene creato su ogni iterazione del forciclo. Ciò significa che in ogni iterazione viene allocata una piccola quantità di memoria per creare un Stringoggetto.

Tornando al codice, possiamo vedere che una volta eseguita una singola iterazione, nell'iterazione successiva, l' Stringoggetto che era stato creato nell'iterazione precedente non viene più utilizzato - quell'oggetto è ora considerato "spazzatura".

Alla fine, inizieremo a ricevere molta spazzatura e la memoria verrà utilizzata per gli oggetti che non vengono più utilizzati. Se continua così, alla fine la Java Virtual Machine esaurirà lo spazio per creare nuovi oggetti.

È qui che entra in gioco il garbage collector.

Il garbage collector cercherà gli oggetti che non vengono più utilizzati e se ne sbarazza, liberando la memoria in modo che altri nuovi oggetti possano utilizzare quel pezzo di memoria.

In Java, la gestione della memoria è curata dal garbage collector, ma in altri linguaggi come C, è necessario eseguire la gestione della memoria autonomamente utilizzando funzioni come mallocefree . La gestione della memoria è una di quelle cose in cui è facile commettere errori, che possono portare a quelle che vengono chiamate perdite di memoria - luoghi in cui la memoria non viene recuperata quando non sono più in uso.

Gli schemi di gestione automatica della memoria come la garbage collection fanno in modo che il programmatore non debba preoccuparsi troppo dei problemi di gestione della memoria, in modo che possa concentrarsi maggiormente sullo sviluppo delle applicazioni di cui ha bisogno per sviluppare.


Sarebbe vero dire che un'applicazione Java in esecuzione su un computer dispone di due funzionalità di garbage collection. Uno con la macchina virtuale Java. E poi uno sulla macchina reale che esegue Windows? (O qualsiasi altro sistema operativo)
Lealo

No, di solito le applicazioni Java vengono eseguite solo se è presente JRE. Quindi, è richiesta solo la funzionalità di garbage collection di JVM! @Lealo
Am_I_Helpful

18

Libera la memoria allocata agli oggetti che non vengono più utilizzati dal programma, da cui il nome "garbage". Per esempio:

public static Object otherMethod(Object obj) {
    return new Object();
}

public static void main(String[] args) {
    Object myObj = new Object();
    myObj = otherMethod(myObj);
    // ... more code ...  
}

So che è estremamente artificioso, ma qui, dopo aver chiamato otherMethod()l'originale Objectcreato, viene reso irraggiungibile - e questa è "spazzatura" che viene raccolta dalla spazzatura.

In Java il GC viene eseguito automaticamente, ma puoi anche chiamarlo esplicitamente con System.gc()e provare a forzare una grande raccolta di dati inutili. Come sottolinea Pascal Thivent, non dovresti davvero farlo e potrebbe fare più male che bene (vedi questa domanda ).

Per ulteriori informazioni, vedere la voce di wikipedia su Garbage collection e Tuning Garbage Collection (da Oracle)


1
AFAIK System.gc()non forza l'esecuzione di GC.
Itay Karo

1
+1 per il buon esempio di codice. Si noti che è perfettamente valido che il GC venga distrutto myObjprima che abbia luogo la chiamata a otherMethod, perché myObjnon è più accessibile a quel punto.
Billy ONeal

@Italy credo che sia specifica dell'implementazione.
NullUserException

2
Credo che non si debba chiamare System.gc(), il punto centrale di avere un GC è non doverlo fare.
Pascal Thivent

con l'analisi dell'escape ( en.wikipedia.org/wiki/Escape_analysis ), è possibile che la JVM non alloca nemmeno l'oggetto in primo luogo in questo esempio. L'intera creazione dell'oggetto può (in teoria) essere ottimizzata. L'implementazione dipende ovviamente.
mikera

15

Un oggetto diventa idoneo per Garbage Collection o GC se non è raggiungibile da alcun thread attivo o da riferimenti statici.

In altre parole, puoi dire che un oggetto diventa idoneo per la garbage collection se tutti i suoi riferimenti sono nulli. Le dipendenze cicliche non vengono conteggiate come riferimento, quindi se l'oggetto A ha un riferimento all'oggetto B e l'oggetto B ha un riferimento all'oggetto A e non hanno nessun altro riferimento attivo, entrambi gli oggetti A e B saranno idonei per la Garbage Collection.


Generazioni di heap per la raccolta dei rifiuti -

Gli oggetti Java vengono creati Heape Heapsono divisi in tre parti o generazioni per motivi di garbage collection in Java, questi sono chiamati Young (New) generation, Tenured (Old) Generation e Perm Area of the heap.

Java Heap Space New Generation è ulteriormente suddivisa in tre parti note come spazio Eden, spazio Survivor 1 e spazio Survivor 2. Quando un oggetto viene creato per la prima volta in un mucchio, viene creato in una nuova generazione all'interno dello spazio Eden e dopo la successiva raccolta di rifiuti minori se un oggetto sopravvive viene spostato nel sopravvissuto 1 e poi nel sopravvissuto 2 prima che la raccolta dei rifiuti principale spostasse quell'oggetto nella generazione vecchia o di ruolo .

Lo spazio perm di Java Heap è dove JVM memorizza i metadati su classi e metodi, pool di stringhe e dettagli a livello di classe.

Generazioni di heap per Garbage Collection

Fare riferimento qui per ulteriori informazioni: Garbage Collection


Non è possibile forzare JVM a eseguire Garbage Collection sebbene sia possibile effettuare una richiesta utilizzando il metodo System.gc()o Runtime.gc().

In java.lang.System

public static void gc() {
    Runtime.getRuntime().gc();  
}

In java.lang.Runtime

public native void gc();  // note native  method

Algoritmo Mark and Sweep -

Questo è uno degli algoritmi più popolari usati dalla Garbage Collection. Qualsiasi algoritmo di garbage collection deve eseguire 2 operazioni di base. Uno, dovrebbe essere in grado di rilevare tutti gli oggetti irraggiungibili e in secondo luogo, deve recuperare lo spazio di heap utilizzato dagli oggetti spazzatura e rendere di nuovo lo spazio disponibile per il programma.

Le operazioni di cui sopra vengono eseguite da Mark e Sweep Algorithm in due fasi:

  1. Segna fase
  2. Fase di spazzata

leggi qui per maggiori dettagli - Mark and Sweep Algorithm


6

garbage collector implica che gli oggetti che non sono più necessari al programma sono "spazzatura" e possono essere gettati via.


6

Garbage Collector fa parte di JRE che garantisce che gli oggetti a cui non si fa riferimento vengano liberati dalla memoria.
Di solito viene eseguito quando la tua app esaurisce la memoria. AFAIK contiene un grafico che rappresenta i collegamenti tra gli oggetti e gli oggetti isolati possono essere liberati.
Per risparmiare le prestazioni, gli oggetti correnti raggruppati in generazioni, ogni volta che GC esegue la scansione di un oggetto e scopre che è ancora referenziato, il conteggio della generazione viene incrementato di 1 (a un valore massimo massimo, 3 o 4 credo) e la nuova generazione viene scansionata per prima (più breve è l'oggetto in memoria, più probabilmente non è più necessario) quindi non tutti gli oggetti vengono scansionati ogni volta che GC viene eseguito.
leggi questo per maggiori informazioni.


@quantumSoup sei propenso a questo? Credo che una sorta di raccolta dei rifiuti (più costosa) avvenga solo quando l'heap si riempie.
Pablo Fernandez

2
@quantumSoup: dipende dall'implementazione GC di JRE. In molti casi, il GC non viene eseguito costantemente. Invece, viene eseguito quando l'app non è in grado di allocare un oggetto perché l'heap è pieno. Le JVM HotSpot recenti includono un GC parallelo, ma non è abilitato per impostazione predefinita.
Stephen C

Questa risposta si concentra troppo sul meccanismo. La domanda era "Cos'è il garbage collector", non "Come funziona il garbage collector"
Billy ONeal

@quantum: ha neutralizzato il tuo -1, perché: apprendimento, cioè, a cosa serve questa pagina, giusto? Per imparare devi sbagliare. Punire gli errori fa sì che le persone non imparino. Spero che tu possa essere d'accordo su questo punto. E forse hai fatto un errore qui.
erikbwork

1
@erikb: Con questa logica non ci sarebbero mai voti negativi. E i voti negativi sono necessari per eliminare le risposte relativamente scarse. L'OP è ovviamente un principiante e il funzionamento interno specifico del GC semplicemente non è importante per la domanda posta. Poiché questa risposta non risponde alla domanda posta (risponde a una diversa), i voti negativi sono perfettamente giustificati.
Billy ONeal

3

Il garbage collector consente al tuo computer di simulare un computer con memoria infinita. Il resto è solo meccanismo.

Lo fa rilevando quando i blocchi di memoria non sono più accessibili dal codice e restituendo quei blocchi all'archivio gratuito.

EDIT: Sì, il collegamento è per C #, ma C # e Java sono identici a questo proposito.


In realtà c'è una domanda su SO circa la differenza tra Java e s 'C # GC: stackoverflow.com/questions/492703/c-vs-java-garbage-collector
NullUserException

3

Molte persone pensano che la garbage collection raccolga e scarti gli oggetti morti.
In realtà, la garbage collection di Java sta facendo l'opposto! Gli oggetti vivi vengono tracciati e tutto il resto viene designato come spazzatura.

Quando un oggetto non viene più utilizzato, il Garbage Collector recupera la memoria sottostante e la riutilizza per l'allocazione futura degli oggetti. Ciò significa che non vi è alcuna cancellazione esplicita e nessuna memoria viene restituita al sistema operativo. Per determinare quali oggetti non sono più in uso, la JVM esegue in modo intermittente quello che è giustamente chiamato algoritmo mark-and-sweep.

Controlla questo per maggiori informazioni dettagliate: http://javabook.compuware.com/content/memory/how-garbage-collection-works.aspx


1

Per dirla nei termini più semplici che anche un non programmatore può capire, quando un programma elabora i dati crea dati intermedi e spazio di archiviazione (variabili, array, determinati metadati di oggetti ecc.) Per quei dati.

Quando si accede a questi oggetti tramite funzioni o oltre una certa dimensione, vengono allocati da un heap centrale. Quindi, quando non sono più necessari, devono essere ripuliti.

Ci sono alcuni ottimi articoli online su come funziona, quindi tratterò solo la definizione di base.

Il GC è fondamentalmente la funzione che esegue questa pulizia. Per fare ciò, cancella le voci della tabella a cui non fa riferimento alcun oggetto attivo, eliminando di fatto gli oggetti, quindi copia e compatta la memoria. È un po 'più complicato di così, ma hai capito.

Il grosso problema è che alcune parti in cui questo processo spesso richiede che l'intera Java VM venga interrotta temporaneamente per poter essere eseguita, così come l'intero processo è molto impegnativo per il processore e la larghezza di banda della memoria. Le varie opzioni a partire dai GC e le opzioni di ottimizzazione per ciascuno sono progettate per bilanciare questi vari problemi con l'intero processo GC.


0

Garbage Collection in Java (e anche in altri linguaggi / piattaforme) è un modo per l'ambiente run-time java (JRE) di riutilizzare la memoria da oggetti java che non sono più necessari. Semplicisticamente, quando JRE si avvia inizialmente, richiede al sistema operativo (O / S) una certa quantità di memoria. Quando JRE esegue le tue applicazioni, utilizza quella memoria. Quando la tua applicazione ha finito di usare quella memoria, il "Garbage Collector" di JRE arriva e recupera quella memoria per usarla da parti differenti delle tue applicazioni esistenti. Il "Garbage Collector" di JRE è un'attività in background che è sempre in esecuzione e cerca di selezionare i momenti in cui il sistema è inattivo per eseguire le sue operazioni di spazzatura.

Un'analogia con il mondo reale sarebbero gli uomini della spazzatura che vengono a casa tua e raccolgono la tua spazzatura riciclabile ... alla fine, viene riutilizzata in altri modi da te e / o da altre persone.


0

Il Garbage Collector può essere visualizzato come un gestore del conteggio dei riferimenti. se viene creato un oggetto e il suo riferimento è memorizzato in una variabile, il conteggio dei riferimenti viene aumentato di uno. durante il corso dell'esecuzione se quella variabile viene assegnata con NULL. il conteggio dei riferimenti per quell'oggetto viene decrementato. quindi il conteggio dei riferimenti corrente per l'oggetto è 0. Ora, quando viene eseguito Garbage Collector, controlla gli oggetti con conteggio dei riferimenti 0. e libera le risorse assegnate ad esso.

Il richiamo del Garbage Collector è controllato dai criteri di Garbage Collection.

Puoi ottenere alcuni dati qui. http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html


1
Il conteggio dei riferimenti è un modo pessimo per implementare GC. Non credo che nessuna delle principali implementazioni JVM lo utilizzi.
NullUserException

0

Garbage Collector è un componente di jvm.

Viene utilizzato per raccogliere spazzatura ogni volta che la CPU viene liberata.

Qui garbage significa oggetti inutilizzati che viene eseguito in Background del programma principale

per monitorare lo stato del programma principale.


0

La garbage collection automatica è il processo di analisi della memoria heap, identificazione degli oggetti in uso e quali no e dell'eliminazione degli oggetti inutilizzati. Un oggetto in uso, o un oggetto referenziato, significa che una parte del programma mantiene ancora un puntatore a quell'oggetto. Un oggetto inutilizzato, o un oggetto non referenziato, non è più referenziato da nessuna parte del programma. Quindi la memoria utilizzata da un oggetto non referenziato può essere recuperata.

In un linguaggio di programmazione come C, l'allocazione e la deallocazione della memoria è un processo manuale. In Java, il processo di deallocazione della memoria viene gestito automaticamente dal Garbage Collector. Si prega di controllare il collegamento per una migliore comprensione. http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html


0

La raccolta di dati inutili si riferisce al processo di liberazione automatica della memoria nell'heap eliminando gli oggetti che non sono più raggiungibili nel programma. L'heap è una memoria a cui ci si riferisce come archivio gratuito, rappresenta un grande pool di memoria inutilizzata allocata all'applicazione Java.


1
Non utilizzare la formattazione delle virgolette per il testo che non è citato e se è citato devi citare la fonte.
Marchese di Lorne

0

I principi di base della garbage collection sono trovare gli oggetti dati in un programma a cui non sarà possibile accedere in futuro e recuperare le risorse utilizzate da quegli oggetti. https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29

vantaggi

1) Salva dai bug, che si verificano quando un pezzo di memoria viene liberato mentre ci sono ancora dei puntatori ad esso, e uno di quei puntatori viene dereferenziato. https://en.wikipedia.org/wiki/Dangling_pointer

2) Double free bugs, che si verificano quando il programma cerca di liberare una regione di memoria che è già stata liberata, e forse già allocata di nuovo.

3) Previene alcuni tipi di perdite di memoria, in cui un programma non riesce a liberare memoria occupata da oggetti diventati irraggiungibili, il che può portare all'esaurimento della memoria.

svantaggi

1) Consumo di risorse aggiuntive, impatti sulle prestazioni, possibili blocchi nell'esecuzione del programma e incompatibilità con la gestione manuale delle risorse. La garbage collection consuma risorse di elaborazione per decidere quale memoria liberare, anche se il programmatore potrebbe già conoscere queste informazioni.

2) Il momento in cui la spazzatura viene effettivamente raccolta può essere imprevedibile, con conseguenti stalli (pause per spostare / liberare memoria) sparsi durante una sessione. Gli stalli imprevedibili possono essere inaccettabili negli ambienti in tempo reale, nell'elaborazione delle transazioni o nei programmi interattivi.


Tutorial Oracle http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

La garbage collection è il processo che identifica quali oggetti sono in uso e quali no, e cancella gli oggetti inutilizzati.

In un linguaggio di programmazione come C, C ++, allocare e liberare memoria è un processo manuale.

int * array = new int[size];
processArray(array); //do some work.
delete array; //Free memory

Il primo passaggio del processo si chiama marcatura. Qui è dove il garbage collector identifica quali pezzi di memoria sono in uso e quali no.

Passaggio 2a. L'eliminazione normale rimuove gli oggetti non referenziati lasciando gli oggetti referenziati e i puntatori nello spazio libero.

Per migliorare le prestazioni, vogliamo eliminare gli oggetti non referenziati e compattare anche gli oggetti referenziati rimanenti. Vogliamo mantenere insieme gli oggetti referenziati, quindi sarà più veloce allocare nuova memoria.

Come affermato in precedenza, dover contrassegnare e compattare tutti gli oggetti in una JVM è inefficiente. Man mano che vengono allocati sempre più oggetti, l'elenco di oggetti cresce e cresce portando a tempi di raccolta dei rifiuti sempre più lunghi.

Continua a leggere questo tutorial e saprai come GC affronta questa sfida.

In breve, ci sono tre regioni dell'heap, YoungGeneration per oggetti di breve durata, OldGeneration per oggetti di lungo periodo e PermanentGeneration per oggetti che vivono durante la vita dell'applicazione, ad esempio, classi, librerie.


0

Poiché gli oggetti vengono allocati dinamicamente dal nuovo operatore, è possibile chiedere come vengono distrutti questi oggetti e come viene liberata la memoria occupata. In altri linguaggi come C ++, è necessario liberare dinamicamente gli oggetti allocati manualmente dall'operatore di eliminazione. Java ha un approccio diverso; gestisce automaticamente la deallocazione. La tecnica è nota come Garbage Collection .

Funziona così: quando non ci sono riferimenti a un oggetto, si presume che questo oggetto non sia più necessario e si può recuperare la memoria occupata dall'oggetto. Non è necessario distruggere esplicitamente gli oggetti come in C ++. La raccolta di dati inutili si verifica sporadicamente durante l'esecuzione del programma; Non accade semplicemente perché ci sono uno o più oggetti che non vengono più utilizzati. Inoltre, diverse implementazioni di runtime Java hanno approcci diversi alla raccolta dei rifiuti, ma la maggior parte dei programmatori non deve preoccuparsi di questo quando scrive programmi.


-2

La garbage collection automatica è un processo in cui la JVM elimina o mantiene in memoria determinati punti dati per liberare spazio per il programma in esecuzione. La memoria viene prima inviata alla memoria heap, cioè dove il garbage collector (GC) fa il suo lavoro, quindi si decide di terminare o conservare. Java presume che il programmatore non possa sempre essere considerato attendibile, quindi termina gli elementi che ritiene di non aver bisogno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.