2010-11-14 5 views
8

Tengo curiosidad por saber cómo manejarán las últimas JVM la memoria recolectora de basura reservada por el siguiente método.¿El método List subList() previene la recolección de basura del resto de la lista?

public List<Player> getHallOfFame() { 
    ArrayList<Player> listToSort = new ArrayList<Player>(map.values()); 
    Collections.sort(listToSort, comparator); 

    return listToSort.subList(0, 5); 
} 

En el peor que se puede imaginar la JVM mantener todo el contenido de listToSort en la memoria siempre y cuando no se mantienen las referencias a la lista secundaria. ¿Alguien sabe si ese es realmente el caso? Estoy particularmente interesado en los enlaces que pueden probar esto de una forma u otra para JVM específicas.

+0

Creo que .subList devuelve una nueva lista, y listToSort saldrá del alcance, por lo que se recogerá la basura. –

+3

@Paul: la documentación indica lo contrario. –

+0

Sí, la clave aquí está respaldada por la lista original, por lo que cualquier cambio en la lista original se refleja en la lista secundaria. – CoolBeans

Respuesta

10

Sí, subList es solo una "vista" en la lista existente. Todos los datos están realmente en la lista original. De la documentación:

La lista devuelta está respaldada por esta lista, por lo que los cambios no estructurales en la lista devuelta se reflejan en esta lista, y viceversa.

Así que sí, devolver una sub-lista evitará que la lista original sea recogida.

Si no quiere ese efecto, básicamente necesita hacer una copia de la sublista relevante. Por ejemplo:

return new ArrayList<Player>(listToSort.subList(0, 5)); 
+0

Gracias Jon. La única razón por la que pensé que las cosas podrían ser diferentes es que el análisis estático podría demostrar que la lista original ya no se podía cambiar. – Caoilte

+3

@Caoilte: las cosas como la reflexión dificultan ese tipo de análisis. –

0

Creo que tiene razón. Dado que la sublista está respaldada por la lista original. A partir de la documentación de Java:

Devuelve una vista de la parte de esta lista entre el fromIndex especificado, inclusive, y toIndex, exclusivo. (Si fromIndex y toIndex son iguales, la lista devuelta está vacía.) La lista devuelto está respaldado por esta lista, por lo cambios no estructurales en la lista devuelto se reflejan en esta lista, y vice-versa. La lista devuelta admite todas las operaciones de lista opcionales compatibles con esta lista.

1

subList crea una nueva instancia de AbstractList.SubList, que guarda una referencia a la lista original. Por lo tanto, si mantiene la variable devuelta por getHallOfFame, evitará que el gc limpie listToSort.

Cuestiones relacionadas