2009-02-22 17 views
11

temo questa è una domanda davvero stupida, ma qui va:clear() impl in ListaLinkata di Java

Perché il metodo chiaro nella implementazione predefinita ListaLinkata di Java fastidio a camminare l'elenco e sganciare tutti i nodi? Perché non solo sganciare l'intestazione e lasciare collegato il resto dell'elenco: il GC lo otterrà comunque, no?

Ecco il metodo:

/** 
* Removes all of the elements from this list. 
*/ 
public void clear() { 
    Entry<E> e = header.next; 
    while (e != header) { 
     Entry<E> next = e.next; 
     e.next = e.previous = null; 
     e.element = null; 
     e = next; 
    } 
    header.next = header.previous = header; 
    size = 0; 
modCount++; 
} 

Perché camminare? Perché non saltare semplicemente a header.next = header.previous = header;?

Il meglio che posso capire è che aiuta il GC ...? Questo link http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html#997442 suggerisce questo.

TIA ...

risposta

18

Il loro metodo assicura che, anche se l'altro codice detiene ancora i riferimenti a nodi particolari, saranno GC'ed gli altri nodi.

In caso contrario, anche un singolo riferimento esterno a uno dei nodi impedirebbe la raccolta dell'intera catena.

Inoltre, altre operazioni nell'elenco potrebbero essere attive contemporaneamente (ad esempio visualizzazioni tramite subList() o Collections.unmodifiableList(), iteratori), e ciò garantisce che tali elementi percepiscano l'elenco come "vuoto" immediatamente.

+0

Sono stato impostato per non essere d'accordo, dicendo che non c'è modo per codice esterno di ottenere un riferimento a una voce LinkedList $ ... ma indirettamente tramite LinkedList $ ListItr si può sicuramente ... Grazie e buona cattura! – overthink

+0

Cosa mancherebbe un nodo? Un Iterator o subList, ma questi non sarebbero validi, quindi non ci sarebbe da mantenere. –

+0

@Tom: se non si esegue questa operazione, la subList e Iterator continueranno a funzionare, ma il framework di raccolta tenta di essere a prova di errore (ma non lo garantisce). –

2

IIRC, si trattava di una modifica apportata in JDK6 per assistere le prestazioni di alcuni algoritmi GC (generazionali). Spesso, lo stesso List nodi e nodi precedenti si troveranno in una generazione precedente rispetto ad altri nodi. Le generazioni più giovani verranno raccolte più frequentemente, con il risultato che i nodi giovani vengono copiati prima di scoprire che tutti i nodi sono spazzatura.

Quindi si tratta di un piccolo miglioramento delle prestazioni. L'ottimizzazione delle prestazioni della memoria è un po 'strana in quanto spesso non è il codice che causa il problema che richiede più tempo per l'esecuzione.

0

Stavo solo speculando su questo problema sul mio blog di sviluppo di giochi. Grazie per la risposta. Direi che l'esposizione del nodo è stata un'indennità di progettazione discutibile. È anche discutibile che visualizzazioni alternative sull'elenco (iteratori e così via) si baserebbero sul nodo che si scollega per il fail-fast. Invece di basarsi su questo comportamento con effetti collaterali, le sottoview nell'elenco dovrebbero controllare il conteggio delle modifiche. In ogni caso, vedo perché sono rimasti bloccati ora.

0

Il codice sorgente di java.util.LinkedList a http://developer.classpath.org/doc/java/util/LinkedList-source.html suggerisce che si può semplicemente impostare il primo e l'ultimo elemento a null.

Ovviamente se si tende a essere eccessivamente protettivi, è possibile scorrere l'intero processo. Personalmente ritengo che questo possa essere un compito molto costoso se la tua lista contiene diverse migliaia di elementi.