c - ¿Qué son los punteros fuertes y los punteros débiles?
android-source android-binder (3)
Android debe programarse en Java, no en C. Cualquier documentación del equipo de Android haría referencia a ese idioma. En Java hay referencias fuertes y débiles. Una referencia débil no impide que el recolector de basura la limpie, una referencia fuerte sí lo hace. Se utilizan para almacenar en caché en algunos sistemas operativos, pero en Android a partir de la versión 3.0 que solo contiene referencias débiles a un objeto significa que se recopilará de inmediato.
C no tiene equivalente de una referencia débil, ya que no tiene recolección de basura.
Estoy confundido con la noción de "puntero fuerte" y "puntero débil". Diane Hackborn misma dijo que:
El objeto permanecerá alrededor mientras haya punteros fuertes; Se destruye una vez que se libera el último. Todo lo que puede hacer con un puntero débil es comparar e intentar promocionar a un puntero fuerte; este último fallará si no hay otros punteros fuertes en el objeto.
Lo que no me queda claro. ¿Un puntero fuerte es equivalente a un puntero compartido ( boost::
:)? ¿Y cuál es el papel de un puntero débil si está allí solo para intentar promocionarse a un puntero fuerte? Al igual que, ¿cuándo necesitamos punteros débiles y fuertes?
Actualizar:
Gracias a todos, pero estoy preguntando específicamente sobre el kernel sp
y wp
Android, y no tienen nada que ver con las referencias de Java.
Básicamente, estoy intentando descifrar el código aquí http://www.androidenea.com/2010/03/share-memory-using-ashmem-and-binder-in.html Y realmente no entiendo el uso de sp
y wp
Actualizar:
La respuesta real se encuentra en los comentarios de la respuesta aceptada. Gracias a Gabe Sechan:
Los punteros fuertes y débiles son diferentes implementaciones de punteros inteligentes y hacen casi lo mismo: cuando un puntero sale del alcance, siempre que al menos un puntero fuerte haga referencia a él, no se liberará. Si solo son referencias débiles (o nada) serán referencias. La comprobación se realiza siempre que una referencia fuerte o débil a ella se haya descopado.
Si tengo 10 punteros débiles que hacen referencia al mismo objeto, y uno de esos 10 queda fuera del alcance, ¿se destruirá el objeto? Mientras que con punteros fuertes, solo cuando los 10 salgan de su alcance, ¿se destruirá el objeto?
Si casi. Si todo lo que tiene son 10 punteros débiles, probablemente ya habría salido del alcance, cuando el último puntero fuerte se salió del alcance. La implementación puede permitir que permanezca un poco más tiempo si hay memoria de repuesto, pero se cortará si se encuentra en una condición de memoria baja y no parece que su implementación sea tan avanzada de su presupuesto. Y el uso de esto sigue siendo principalmente el almacenamiento en caché, es más o menos equivalente a un aumento de shared_ptr y un aumento de weak_ptr. Básicamente, un puntero débil puede hacer que el objeto al que hace referencia desaparezca en cualquier momento.
Esta es una buena publicación que discute la diferencia entre la referencia regular (o "StrongReference"), SoftReference
s, WeakReference
s, e incluso PhantomReference
s en Java, disfrute de: http://weblogs.java.net/blog/2006/05/04/understanding-weak-references
sp significa StrongPointer en Android, la memoria que ocupa el objeto señalado se liberará si el recuento de referencia es igual a 0. wp significa WeakPointer, por lo que si tengo un puntero débil, no me importa si el objeto al que se hace referencia está vivo o no . Puede ser usado en algunos escenarios de caché y comparación.
Primero, eche un vistazo rápido a la implementación sp en StrongPointer.h .
Es simplemente una envoltura para el recuento de referencias. Por ejemplo,
template<typename T> template<typename U>
sp<T>& sp<T>::operator = (U* other)
{
if (other) ((T*)other)->incStrong(this);
if (m_ptr) m_ptr->decStrong(this);
m_ptr = other;
return *this;
}
Si crea un puntero fuerte por sp<IBinder> strongPointer
, m_ptr es el objeto al que se hace referencia. Como puede ver en el código fuente, la plantilla sp solo representa un puntero fuerte para que el sistema no libere la memoria mientras mantenga esta sp. No mantiene un contador de referencia. El contador se mantiene en la clase RefBase . Y para utilizar el StrongPointer, su objeto debe ser una instancia de RefBase.
La clase RefBase mantiene el contador de referencia fuerte y el contador de referencia débil, la única diferencia es que el objeto referenciado se liberará si el valor fuerte cuenta a 0. Además, para un objeto administrado por Refbase, puede ser referenciado por algunos punteros fuertes y punteros débiles simultáneamente.
Puede ver un amplio uso de StrongPointers en el marco de Android, la mayoría de ellos están en el objeto IBinder, un objeto de enlace nativo puede pasar a través de diferentes procesos. Los diferentes procesos pueden mantener los punteros fuertes a un mismo objeto, el objeto no será revocado por el sistema mientras un proceso aún mantenga el puntero.