Domanda

Speriamo che sia una domanda semplice. Prendi ad esempio un elenco collegato in modo circolare:

class ListContainer
{
  private listContainer next;
  <..>

  public void setNext(listContainer next)
  {
    this.next = next;
  }
}

class List
{
  private listContainer entry;
  <..>
}

Ora poiché è un elenco collegato in modo circolare, quando viene aggiunto un singolo elemnt, ha un riferimento a se stesso nella sua prossima variabile. Quando si elimina l'unico elemento nell'elenco, la voce è impostata su null. È necessario impostare ListContainer.next su null anche per Garbage Collector per liberare la sua memoria o gestisce tali riferimenti automatici automagicamente?

È stato utile?

Soluzione

I garbage collector che si basano esclusivamente sul conteggio dei riferimenti sono generalmente vulnerabili alla mancata raccolta di strutture autoreferenziali come questa. Questi GC si basano su un conteggio del numero di riferimenti all'oggetto per calcolare se un determinato oggetto è raggiungibile.

Approcci di conteggio non di riferimento applicano un test di raggiungibilità più completo per determinare se un oggetto è idoneo alla raccolta. Questi sistemi definiscono un oggetto (o un insieme di oggetti) che si presume siano sempre raggiungibili. Qualsiasi oggetto per il quale sono disponibili riferimenti da questo grafico a oggetti è considerato non idoneo per la raccolta. Qualunque oggetto non direttamente accessibile da questo oggetto non lo è. Pertanto, i cicli non finiscono per influire sulla raggiungibilità e possono essere raccolti.

Vedi anche, la pagina di Wikipedia su rintracciare i garbage collector .

Altri suggerimenti

I riferimenti circolari sono un problema (risolvibile) se si fa affidamento sul conteggio dei riferimenti per decidere se un oggetto è morto. Nessuna implementazione Java utilizza il conteggio dei riferimenti, AFAIK. I Sun JRE più recenti utilizzano un mix di diversi tipi di GC, tutti mark-and-sweep o copie, credo.

Puoi leggere di più sulla raccolta dei rifiuti in generale su Wikipedia e alcuni articoli su java GC qui e qui , ad esempio.

La risposta effettiva a questo dipende dall'implementazione. Sun JVM tiene traccia di alcuni insiemi di oggetti radice (thread e simili) e, quando deve eseguire una garbage collection, traccia quali oggetti sono raggiungibili da quelli e li salva, scartando il resto. In realtà è più complicato di quello per consentire alcune ottimizzazioni, ma questo è il principio di base. A questa versione non interessano i riferimenti circolari: purché nessun oggetto vivo contenga un riferimento a uno morto, può essere GCed.

Altre JVM possono utilizzare un metodo noto come conteggio dei riferimenti. Quando viene creato un riferimento all'oggetto, un certo contatore viene incrementato e quando il riferimento esce dall'ambito, il contatore viene diminuito. Se il contatore raggiunge lo zero, l'oggetto viene finalizzato e la garbage collection. Questa versione, tuttavia, consente la possibilità di riferimenti circolari che non verrebbero mai raccolti. A titolo di salvaguardia, molte di queste JVM includono un metodo di backup per determinare quali oggetti sono effettivamente morti e vengono eseguiti periodicamente per risolvere i riferimenti personali e deframmentare l'heap.

A parte una mancata risposta (le risposte esistenti sono più che sufficienti), potresti voler dare un'occhiata a un white paper sul sistema di raccolta dei rifiuti JVM se sei interessato a GC. (Qualsiasi, solo google JVM Garbage Collection)

Sono rimasto sorpreso da alcune delle tecniche utilizzate e durante la lettura di alcuni concetti come "Eden". Ho capito per la prima volta che Java e JVM potevano davvero battere C / C ++ in velocità. (Ogni volta che C / C ++ libera un oggetto / blocco di memoria, viene coinvolto il codice ... Quando Java libera un oggetto, in realtà non fa nulla; dato che in un buon codice OO, la maggior parte degli oggetti viene creata e liberata quasi immediatamente, questo è incredibilmente efficiente.)

I GC moderni tendono ad essere molto efficienti, gestendo gli oggetti più vecchi in modo molto diverso rispetto ai nuovi oggetti, essendo in grado di controllare i GC in modo che siano corti e semi-cotti o lunghi e approfonditi, e molte opzioni GC possono essere gestite dagli switch della riga di comando quindi è utile sapere a cosa effettivamente si riferiscono tutti i termini.

Nota: ho appena realizzato che era fuorviante. L'allocazione STACK di C ++ è molto veloce - il mio punto era sull'allocazione di oggetti che sono in grado di esistere al termine della routine corrente (che credo DOVREBBERO essere tutti gli oggetti - è qualcosa a cui non dovresti pensare se stai per pensare in OO, ma in C ++ la velocità potrebbe renderlo poco pratico).

Se stai allocando solo classi C ++ nello stack, la sua allocazione sarà almeno veloce come quella di Java.

Java raccoglie tutti gli oggetti che non sono raggiungibili. Se nient'altro ha un riferimento alla voce, verrà raccolto, anche se ha un riferimento a se stesso.

sì Java Garbage Collector gestisce l'autoreferenziazione!

How?

Esistono oggetti speciali chiamati root garbage-collection (GC roots). Questi sono sempre raggiungibili, così come qualsiasi oggetto che li abbia nella propria radice.

Una semplice applicazione Java ha le seguenti radici GC:

  1. Variabili locali nel metodo principale
  2. Il thread principale
  3. Variabili statiche della classe principale

inserisci qui la descrizione dell'immagine

Per determinare quali oggetti non sono più in uso, la JVM esegue in modo intermittente quello che viene molto appropriatamente chiamato algoritmo mark-and-sweep . Funziona come segue

  1. L'algoritmo attraversa tutti i riferimenti agli oggetti, a partire dal GC radica e segna ogni oggetto trovato come vivo.
  2. Tutta la memoria dell'heap che non è occupata da oggetti contrassegnati è bonificata. È semplicemente contrassegnato come libero, essenzialmente spazzato via oggetti inutilizzati.

Quindi, se un oggetto non è raggiungibile dalle radici GC (anche se è autoreferenziale o referenziato ciclicamente) sarà sottoposto alla garbage collection.

Semplicemente Sì. :)

Scopri http://www.ibm.com/developerworks/ java / library / j-jtp10283 /

Tutti i JDK (da Sun) hanno un concetto di "capacità di raggiungere". Se il GC non può " raggiungere " un oggetto, se ne va.

Non si tratta di " new " info (i primi a rispondere agli intervistati sono fantastici) ma il link è utile e la brevità è qualcosa di dolce. :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top