2008-11-22 15 views
72

¿Puede alguien explicar los principales beneficios de los diferentes tipos de referencias en C#?Beneficios de referencia débiles

  • referencias débiles
  • referencias suaves
  • referencias Phantom
  • referencias fuertes.

Tenemos una aplicación que consume mucha memoria y estamos tratando de determinar si este es un área en la que enfocarnos.

+0

¿Su aplicación hace uso de la clase System.WeakReference específicamente? – MusiGenesis

Respuesta

61

Las referencias suaves y fantasmas provienen de Java, creo. Una referencia débil larga (pase verdadero al constructor WeakReference de C#) se puede considerar similar a la Referencia Phantom de Java. Si hay un análogo a SoftReference en C#, no sé qué es.

Las referencias débiles no extienden la vida útil de un objeto, lo que permite que se recolecte basura una vez que todas las referencias importantes han salido del alcance. Pueden ser útiles para aferrarse a objetos grandes que son costosos de inicializar, pero deberían estar disponibles para la recolección de basura si no se usan activamente.

Si esto será útil o no para reducir el consumo de memoria de su aplicación dependerá completamente de las características específicas de la aplicación. Por ejemplo, si tiene un número moderado de objetos almacenados en caché que pueden o no reutilizarse en el futuro, las referencias débiles podrían ayudar a mejorar el consumo de memoria de los cachés. Sin embargo, si la aplicación está funcionando con una gran cantidad de objetos pequeños, las referencias débiles empeorarán el problema ya que los objetos de referencia ocuparán tanta o más memoria.

+3

Vea también: [Weak References (MSDN)] (http://msdn.microsoft.com/en-us/library/ms404247.aspx) –

35

MSDN tiene una buena explicación de weak references. La cita clave está en la parte inferior donde dice:

Evitar el uso de referencias débiles como una solución automática a la memoria problemas de gestión. En su lugar, desarrolle una política de caché efectiva para manejando los objetos de su aplicación.

Cada vez que he visto una WeakReference en la naturaleza, se ha utilizado como una solución automática para problemas de administración de memoria. Probablemente haya mejores soluciones para los problemas de su aplicación.

+2

Encontré esa cita confusa, porque parece que todo uso de referencias débiles podría ser manejado por la aplicación. En el ejemplo que utiliza la documentación, de un TreeView, la aplicación podría monitorear si el usuario ha usado TreeView por un período de tiempo y, de no ser así, establecer TreeView en nulo, permitiendo que el recolector de elementos no utilizados tenga acceso a él. Eso lograría la misma tarea, pero desde la aplicación. –

+2

@DGGenuine: personalmente, no veo ningún uso para las referencias débiles. Los he encontrado algunas veces en proyectos que heredé de otros desarrolladores, y en cada caso tuve que eliminarlos por completo, ya que los desarrolladores originales no entendieron qué son y para qué están diseñados. – MusiGenesis

+9

@MusiGenesis: 'No veo ningún uso para referencias débiles': Hasta que tenga una pérdida de memoria en su tiempo de ejecución habilitado para GC porque en algún lugar del código hay una referencia a un nodo de árbol que mantiene referenciado todo el árbol, y por lo tanto , ** no ** basura coleccionable a pesar de que ya no se usa. WeakReference se usa como una referencia débil (juego de palabras intencionado): "* Si el objeto todavía está en uso, entonces quiero poder hacer algo con él, pero si ya no está, entonces de ninguna manera quiero ser el que lo mantiene vivo. * "Es la seguridad del código, que determina la propiedad o no de un objeto. – paercebal

4

Brillante ejemplo real con WeakReference se explica en Android development tutorial.

Hay una imagen (mapa de bits) y un contenedor de imágenes en la vista (ImageView). Si la imagen no se cargará desde la memoria (pero, por ejemplo, desde el disco, la red), entonces puede bloquear el hilo de la interfaz de usuario y la pantalla. Para evitarlo, se puede usar una tarea asíncrona.

El problema surge cuando finaliza la tarea asincrónica. El contenedor de imágenes no puede ser útil en absoluto en ese momento (la pantalla se cambia o Android descarga la parte invisible de la vista después de desplazarse). WeakReference puede ayudar aquí y ImageView será basura recolectada.

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> { 
    private final WeakReference<ImageView> imageViewReference; 

    public BitmapWorkerTask(ImageView imageView) { 
     imageViewReference = new WeakReference<ImageView>(imageView); 
    } 
    // Method for getting bitmap is removed for code clearness 

    // Once complete, see if ImageView is still around and set bitmap. 
    @Override 
    protected void onPostExecute(Bitmap bitmap) { 
     if (imageViewReference != null && bitmap != null) { 
      final ImageView imageView = imageViewReference.get(); 
      if (imageView != null) { 
       imageView.setImageBitmap(bitmap); 
      } 
     } 
    } 
} 

P.S. el ejemplo está en Java, pero los desarrolladores de C# lo pueden entender.
Fuente: http://developersdev.blogspot.ru/2014/01/weakreference-example.html

Cuestiones relacionadas