2009-11-28 5 views
8

¿Qué ocurre con WeakReference cuando el objeto de destino al que hace referencia WeakReference.Target ha sido recolectado? ¿El Weakrerence se mantiene vivo y sigue existiendo? La razón por la que estoy preguntando es que tengo una lista de WeakReferences almacenada en una lista. Durante el tiempo de ejecución, las nuevas WeakReferences se agregan constantemente a esa lista. Ahora cuando el objeto objetivo muere, ¿tengo que limpiar yo mismo la WeakReference abandonada? Si es así, ¿hay algún truco inteligente sobre cómo puedo hacer esto? ¿Puedo recibir una notificación cuando se abandona una WeakReference? O tengo que introducir un temporizador que recorre con frecuencia esa lista, para ver si alguna instancia de WeakReference puede eliminarse de esa lista.¿Qué ocurre con una WeakReference después de GC de WeakReference.Target

+0

Por cierto, buen trabajo en la redacción de la pregunta, sentí que estaba muy claro cuál era el problema aunque casi no tengo experiencia con .net. –

Respuesta

12

Este es un problema común con referencias débiles. La referencia en sí permanece viva porque tiene punteros normales. Como sugiere, necesita hacer una "recolección manual de basura" de vez en cuando. Tenga en cuenta que probablemente pueda limpiar los talones en su camino cuando atraviesa la lista por otro motivo. Dependiendo del patrón de uso para la lista, esta recolección de basura "en el lateral" puede ser suficiente.

¡No recorra "con frecuencia" la lista con el único propósito de limpiarla! Cada resguardo solo desperdicia un par de palabras de memoria. Si la lista no se usa a menudo, el costo computacional de limpiarlo a menudo no está justificado, y si se usa con frecuencia se limpiará a sí mismo como se sugirió anteriormente.

Está en otro sistema de recolección de basura en total, pero los problemas son tan similares que puede interesarle this article si puede obtenerlo.

+0

Si no se accederá a la lista por índice, la mejor política es purgarla cuando se agreguen elementos, si el número de elementos que se han agregado entre la última purga y la última colección (use los contadores de GC) excede un cierto fracción del tamaño de la lista. Lo que importa normalmente no es que toda la basura se limpie, sino que la cantidad de basura que no es elegible para la recolección inmediata sigue limitada. Por cierto, las WeakReferences cuestan más que "un par de palabras". No son terriblemente caros, pero incluso un millón de refusores débiles sin usar pueden ahogar un programa. – supercat

6

Dado que tiene una referencia fuerte al objeto WeakReference, no recibirá GC'ed. Esto también es por diseño, ya que se pretendía que todavía pudieras usar WeakReference para descubrir que el objetivo ha sido GC.

Así que sí, tendrás que ir por el modo temporizador.

Agregado: También puede consultar Garbage Collection Notifications.

+1

+1, pero advertiría contra las notificaciones de GC, ya que desactivan algunas de las características más nuevas (agradables) del GC. – user7116

1

El uso previsto es que registre una ReferenceQueue con WeakReferences. Cuando se recopila el objetivo, la referencia se agrega a la cola. Puede sondear o esperar en la cola y eliminar los objetos WeakReference de su Lista.

+2

¿Estás seguro de que este mecanismo es .NET? Creo que te estás refiriendo a Java ... – bitbonk

+0

Oh, lo siento, tuve un poco de ceguera en las etiquetas. No uso .NET, así que confunde cuando las clases tienen exactamente los mismos nombres. – OrangeDog

Cuestiones relacionadas