2009-02-22 15 views
11

Me temo que esto es una pregunta realmente estúpida, pero aquí va:) impl clara (en LinkedList de Java

¿Por qué el método claro en la aplicación Lista enlazada por defecto de Java molestia para caminar por la lista y desenganchar todos los nodos? ¿Por qué no simplemente desenganchar el encabezado y dejar conectado el resto de la lista? El GC lo obtendrá de todos modos, ¿no?

Aquí está el método:

/** 
* 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++; 
} 

Por qué caminar? ¿Por qué no pasar a header.next = header.previous = header;?

Lo mejor que puedo imaginar es que ayuda al GC ...? Este enlace http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html#997442 tipo de sugiere que.

TIA ...

Respuesta

18

Su método asegura que incluso si otro código todavía mantiene referencias a los nodos particulares, serán GC'ed los otros nodos.

De lo contrario, incluso una sola referencia externa a uno de los nodos evitaría que se recolecte toda la cadena.

Además, otras operaciones en la lista podrían estar sucediendo simultáneamente (por ejemplo, vistas a través de subList() o Collections.unmodifiableList(), iteradores), y esto garantiza que esas cosas perciban la lista como "vacía" inmediatamente.

+0

Estaba todo dispuesto a estar en desacuerdo, diciendo que no hay forma de que el código externo obtenga una referencia a LinkedList $ Entry ... pero indirectamente a través de LinkedList $ ListItr, seguro que puede ... ¡Gracias y buena captura! – overthink

+0

¿Qué estaría sosteniendo un nodo? Un iterador o una sublista, pero estos no serían válidos, por lo que no deberían mantenerse. –

+0

@Tom: si no hizo esto, la sublista y el iterador continuarán funcionando, pero el marco de recopilación intenta fallar (pero no lo garantiza). –

2

IIRC, esto fue un cambio realizado en JDK6 para ayudar al rendimiento de ciertos algoritmos GC (generacionales). A menudo, el propio List y los nodos más antiguos estarán en una generación anterior a algunos de los otros nodos. Las generaciones más jóvenes se recogerán con más frecuencia, con el resultado de que los nodos jóvenes se copian antes de que se descubra que todos los nodos son basura.

Por lo tanto, se trata de una optimización de rendimiento menor. La optimización del rendimiento de la memoria es un poco extraña ya que, a menudo, no es el código que causa el problema el que tarda más tiempo en ejecutarse.

0

Solo estaba especulando sobre este tema en mi blog de desarrollo de juegos. Gracias por la respuesta. Yo argumentaría que la exposición del nodo era una concesión de diseño cuestionable. También es incompleto que las vistas alternativas en la lista (iteradores y demás) se basarían en la desvinculación de los nodos a fallas. En lugar de confiar en este comportamiento de efectos secundarios, las sub-vistas en la lista deberían verificar el conteo de modificaciones. En cualquier caso, veo por qué están atrapados con eso ahora.

0

El código fuente de java.util.LinkedList en http://developer.classpath.org/doc/java/util/LinkedList-source.html sugiere que simplemente puede establecer los elementos primero y último en nulo.

Por supuesto, si tiende a ser demasiado protector, puede recorrerlo todo. Personalmente creo que esta puede ser una tarea muy costosa si su lista contiene varios miles de elementos.