Implementación de WeakReference en.NET
clr reference-counting (2)
La clase WeakReference entrega su referencia de objeto al GC y obtiene un identificador. Siempre que obtenga la referencia o verifique si la referencia está activa, el identificador se utiliza para solicitar la referencia al GC.
Esto significa que el GC mantiene una lista de todas las referencias débiles, que debe actualizar cuando se recopilan los objetos. También significa que hay una sobrecarga cada vez que usa una referencia débil.
Entonces, cada referencia débil significa un poco más de trabajo para el recolector de basura, pero por otro lado también lo hace cada referencia regular, incluso si es menos. Por supuesto, debe ser un poco cuidadoso al usar muchas referencias débiles, pero si necesita que la administración de la memoria funcione bien con sus objetos, debería superar la pequeña sobrecarga que genera.
Entiendo y aprecio la utilidad de la clase System.WeakReference en el marco .NET, pero tengo curiosidad por los detalles de la implementación.
¿Cómo se implementa WeakReference en .NET? MSDN discute el uso de WeakReference en detalle, pero tiene pocos detalles que he visto sobre cómo funciona esto bajo el capó.
¿Cómo hace el CLR para rastrear la referencia y saber anular el identificador interno cuando se recolecta el objetivo, sin impedir el GC? ¿Requiere un manejo especial en el propio CLR?
Mi principal preocupación sería si existen implicaciones en el rendimiento de usar WeakReferences (especialmente si se usan muchas de ellas) que difieran de las de usar referencias de objetos estándar.
Usted mencionó MSDN; ¿Ya has visto este artículo?
http://msdn.microsoft.com/en-us/magazine/bb985011.aspx
También puedes ver el capítulo 19 en "Programación de Microsoft .NET Framework aplicada" por el mismo autor (Jeffrey Richter). El capítulo trata sobre la recolección de basura y tiene una sección sobre los aspectos internos de WeakReference.
En general, si está accediendo a una gran cantidad de Targets
dentro de WeakReferences, entonces hay un impacto en el rendimiento simplemente porque WeakRef hace algo de trabajo (principalmente para la seguridad de subprocesos) antes de devolver el objetivo. Esto obviamente no es tan barato como usar la referencia del objeto directamente. Por otro lado, obtiene algo de rendimiento al almacenar referencias a objetos grandes, ya que el recolector de basura tiene más opciones cuando surgen consideraciones de memoria.
Nunca he intentado cuantificar este intercambio, o conocer alguna referencia aquí. Obviamente varía algo dependiendo de la aplicación.