2010-12-29 5 views

risposta

6

Gli oggetti creati nell'ambito del metodo sono idonei per la garbage collection quando il metodo viene chiuso, a meno che tale riferimento non venga restituito come valore di ritorno. In tal caso, il chiamante può o non può aggrapparsi a quel riferimento e impedire che sia gc'd.

Poiché il garbage collector viene eseguito sul proprio thread in base alle proprie spie, non si sa necessariamente quando un oggetto viene ripulito o se gli oggetti allocati altrove sono idonei.

+0

@duffymo: questo non dipende dal fatto che il riferimento dell'oggetto appena creato esista dopo il ritorno della funzione? E.g. un oggetto memorizzato in una raccolta che si trova nell'ambito del chiamante. – Cratylus

+0

@user: in questo caso l'ambito dell'oggetto è stato modificato e potrebbe non essere influenzato da GC. – Jeremy

+0

"Gli oggetti creati nell'ambito del metodo ..." indicano che non è stato inoltrato dall'utente. Hai ragione su una cosa: se l'oggetto creato in ambito viene restituito come valore di ritorno, allora il chiamante può trattenere il riferimento e impedirgli di essere gc'd. Correggerò la mia risposta – duffymo

3

Questo non è così facile - alla fine ogni oggetto viene creato con un metodo.

La VM/compilatore deve effettuare un'analisi del percorso di escape per rilevare se un riferimento di questo oggetto può in qualche modo sfuggire - immaginare di chiamare newObject.toString(). Tu e io sappiamo (spero) che questo non farà del male e l'oggetto non è ancora referenziato, in quanto non si collegherà ad una variabile globale. Ma la VM non lo fa.

Mentre una macchina virtuale moderna eseguirà tale analisi e tratterà oggetti reali di breve durata, speciali nella raccolta di dati inutili, da un punto di vista "di alto livello" sono solo oggetti. Tutto il resto è una sofisticata ottimizzazione a basso livello.

E comunque, come dice duffymo, quando esattamente questi oggetti vengono liberati è incerto.

1

Il fatto che l'esecuzione del metodo sia terminata e che ora l'oggetto sia fuori portata è irrilevante.
La garbage collection è un'operazione implicita del sistema runtime eseguito in una thread separata in parallelo con il codice, implementando un algoritmo specifico di garbage collection.
Il thread di garbage collection viene eseguito a orari imprevedibili, ma molto spesso, ogni secondo circa secondo i documenti java e quando la memoria è quasi esaurita, valutando quali oggetti sono idonei alla raccolta dei dati inutili, ovvero non ci sono riferimenti da root puntatori ad es variabili statiche.
Quindi ogni oggetto accessibile da un puntatore alla radice viene contrassegnato e quindi in modo ricorsivo gli oggetti referenziati da questi oggetti ecc.
Ciò può significare la scansione dell'intero spazio del processo. Una volta terminato, tutti gli oggetti non "segnati" dalla scansione precedente passano alla lista libera (sono GC'd).
Questa è un'operazione pesante, come puoi vedere.

L'esecuzione di tale metodo ha completato .

Quindi il fatto che sei fuori dall'ambito di un metodo che hai chiamato perché è stato completato, è irrilevante. Ciò non significa che il runtime sappia a quel punto che l'oggetto è finito (dal momento che GC è eseguito in parallelo).
Non è come in C++ che alla fine del metodo il programmatore chiamerebbe delete sull'oggetto poiché non è necessario. Nessun "delete" viene automaticamente chiamato alla fine del metodo in Java.
Il thread GC alla fine si renderà conto che non ci sono più riferimenti all'oggetto allocato nello heap dal metodo e CG.
È possibile chiamare il GC in qualsiasi punto se volete da:

System.gc(); 

Ma il GC verrà eseguito prima o poi comunque.
Una cosa da notare è che finché c'è un riferimento a un metodo da un puntatore di root non può essere GC.
Quindi, se nel metodo si crea tramite new un oggetto sull'heap e si memorizza il riferimento in un contenitore statico o lo si restituisce al chiamante, l'oggetto sopravvive al metodo.

+0

La raccolta dei rifiuti è migliorata molto dai tempi di Smalltalk. Nessun VM di tipo commerciale fa più così. Un sacco di informazioni possono essere google su algoritmi reali. – mtraut

+0

System.gc() è più o meno un suggerimento per la VM che sarebbe una buona idea ora attivare un gc. Non puoi contare sul fatto che questo è riconosciuto E (anche se la VM è d'accordo) puoi fare affidamento sul fatto che dopo gc() viene raccolta la spazzatura. Questo è sempre asincrono. – mtraut

+0

@mtraut: anche io mi sto appoggiando a questo.Ma i javadoc sembrano dire diversamente: "Quando il controllo ritorna dalla chiamata al metodo (System.gc), la Java Virtual Machine ha fatto il massimo sforzo per recuperare spazio da tutti gli oggetti scartati" – Cratylus

2

oggetto del ciclo di vita

un programma Java crea molti oggetti di classi diverse. Oggetto in Java, interagire inviando messaggi a vicenda. Al termine dell'elaborazione, questi oggetti vengono quindi raccolti. Dopo il processo di garbage collection, il sistema operativo rivendica le risorse allocate a questi oggetti che saranno ulteriormente utilizzate dai nuovi oggetti.

Sotto sono le fasi in cui un oggetto Java passa attraverso il suo ciclo di vita:

1. Classe Caricare

Prima di creare oggetto da una classe, la classe dovrebbe essere caricato nella memoria dal disco. Il programma di caricamento classe java carica il file di classe in memoria.

Quando viene caricata la classe?

  • quando si crea l'oggetto per la prima volta.

  • qualsiasi campo o metodo statico è accessibile la prima volta.

inizializzatori statici

Java cerca qualsiasi inizializzatori statici e inizializza i campi statici che fanno parte della classe e non fa parte di una specifica istanza della classe (oggetto).

3. creazione oggetto

oggetto è un'istanza della classe. Viene creato nelle seguenti situazioni:

Dichiarazione: quando si dichiara oggetto ad es. Classe A objA; Instantiation: quando new viene utilizzato per allocare un nuovo oggetto nella memoria heap ad es. nuovo ClassA(); Inizializzazione: viene costruito un nuovo oggetto, ad es. Classe A(); 4. Utilizzo dell'oggetto

in questa fase, i programmi possono utilizzare l'oggetto accedendo ai campi o ai metodi di chiamata.

5. Cleanup

Questa è l'ultima fase del oggetti Java dove ottengono riciclati e la memoria è sostenuto dal sistema operativo.

cosa succede in caso di distruzione?

L'oggetto viene rimosso dalla memoria. Java rilascia i suoi riferimenti interni a questo oggetto. Garbage Collection (GC), esegue che libera gli oggetti che non sono più necessari, cioè non ci sono riferimenti a questo oggetto. Finalizzazione: GC offre agli oggetti un'ultima possibilità di ripulire qualsiasi altra risorsa chiamando il suo metodo finalize().

quando succede?

quando l'oggetto esce dall'ambito. Ad esempio {... objA ...}, qui} diventa uno scopo. in questo momento, il runtime Java verifica i riferimenti e consente a GC di riciclare questo oggetto. quando il numero di riferimenti a questo oggetto nella memoria run time di java diventa zero (0). quando l'oggetto è impostato in modo esplicito su null, ad esempio objA = null ;, GC è chiamato finalize() il metodo viene chiamato esplicitamente.

Problemi correlati