web-dev-qa-db-fra.com

Quels sont les pointeurs forts et les pointeurs faibles

Je suis confondu avec la notion de "pointeur fort" et de "pointeur faible". Diane Hackborn elle-même a déclaré:

L'objet restera autour alors qu'il y a des pointeurs forts; il est détruit une fois le dernier sorti. Tout ce que vous pouvez faire avec un pointeur faible est la comparaison et la tentative de promotion vers un pointeur fort; ce dernier échouera s'il n'y a pas d'autres pointeurs forts sur l'objet.

Ce qui est assez peu clair pour moi. Un pointeur fort est-il équivalent à un (boost::) pointeur partagé? Et quel est le rôle d'un pointeur faible s'il n'est là que pour tenter de se promouvoir en pointeur fort? Comme, quand avons-nous besoin de pointeurs faibles et forts?

Mise à jour:

Merci à tous, mais je pose des questions spécifiques sur le noyau d'Android sp et wp, et ils n'ont rien à voir avec les références de Java.

Fondamentalement, j'essaie de casser le code ici http://www.androidenea.com/2010/03/share-memory-using-ashmem-and-binder-in.html Et ne le faites pas comprendre vraiment l'utilisation de sp et wp

Mise à jour:

La réponse réelle réside dans les commentaires de la réponse acceptée. Merci à Gabe Sechan:

Les pointeurs forts et faibles sont différentes implémentations de pointeurs intelligents et font à peu près la même chose: lorsqu'un pointeur sort du domaine, tant qu'au moins un pointeur fort le référence, il ne sera pas libéré. Si seuls les pointeurs faibles (ou rien) y font référence. La vérification est effectuée chaque fois qu'une référence forte ou faible à celle-ci est détendue.

si j'ai 10 pointeurs faibles référençant le même objet, et que l'un de ces 10 est hors de portée, l'objet sera détruit? Alors qu'avec des pointeurs puissants, ce n'est que lorsque les 10 d'entre eux seront hors de portée que l'objet sera détruit?

Oui presque. Si vous n'avez que 10 pointeurs faibles, cela aurait probablement déjà été hors de portée lorsque le dernier pointeur fort est devenu hors de portée. L'implémentation peut lui permettre de rester un peu plus longtemps s'il y a de la mémoire disponible, mais elle sera coupée si vous passez dans une condition de mémoire faible et il ne semble pas que leur implémentation soit aussi avancée que sa citation. Et l'utilisation de ceci est encore principalement la mise en cache - elle est à peu près équivalente à un boost shared_ptr et un boost bold_ptr. Donc, fondamentalement, un pointeur faible peut faire disparaître à tout moment l'objet auquel il fait référence.

26
Yukio Fukuzawa

Android est censé être programmé en Java, pas C. Toute documentation de l'équipe Android référencerait ce langage. Dans Java il y a des références fortes et faibles). Une référence faible n'empêche pas le garbage collector de le nettoyer, une référence forte le fait. Ils sont utilisés pour la mise en cache sur certains systèmes d'exploitation, mais sur Android à partir de 3.0 ne contenant que des références faibles à un objet signifie qu'il sera récupéré immédiatement.

C n'a pas d'équivalent d'une référence faible, car il n'a pas de récupération de place.

12
Gabe Sechan

sp signifie StrongPointer dans Android, la mémoire occupée par l'objet pointé sera libérée si le nombre de références est égal à 0. wp signifie WeakPointer, donc si j'ai un pointeur faible, je me fiche que l'objet référencé soit vivant ou non . Il peut être utilisé dans certains scénarios de cache et de comparaison.

Tout d'abord, jetez un coup d'œil à l'implémentation sp dans StrongPointer.h .

Il s'agit simplement d'un wrapper pour le comptage des références. Par exemple,

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 vous créez un pointeur fort par sp<IBinder> strongPointer, le m_ptr est l'objet référencé. Comme vous pouvez le voir dans le code source, le modèle sp ne représente qu'un pointeur fort afin que le système ne libère pas la mémoire tant que je maintiens ce sp. Il ne maintient pas de compteur de référence. Le compteur est conservé dans la classe RefBase . Et pour utiliser StrongPointer, votre obj doit être une instance de RefBase.

La classe RefBase conserve à la fois un compteur de référence fort et un compteur de référence faible, la seule différence est que l'objet référencé sera libéré si le fort compte jusqu'à 0. De plus, pour un objet géré par Refbase, il peut être référencé simultanément par certains pointeurs forts et pointeurs faibles.

Vous pouvez voir une utilisation répandue de StrongPointers dans Android framework, la plupart d'entre eux sont sur un objet IBinder, un objet liant natif peut passer par différents processus. Différents processus peuvent contenir des pointeurs forts vers un même objet, l'objet ne sera pas révoqué par le système tant qu'un processus tiendra toujours le pointeur.

31
StarPinkER

Ceci est un bon article discutant de la différence entre une référence régulière (ou "StrongReference"), SoftReferences, WeakReferences et même PhantomReferences en Java, profitez de: http : //weblogs.Java.net/blog/2006/05/04/understanding-weak-references

3
Emil Davtyan