web-dev-qa-db-fra.com

Existe-t-il une utilisation pratique pour les références faibles?

Duplicata possible:
Références faibles - à quel point sont-elles utiles?

Étant donné que les références faibles peuvent être réclamées par le ramasse-miettes à tout moment, y a-t-il une raison pratique de les utiliser?

94
user496949

Si vous souhaitez conserver une référence à quelque chose tant qu'il est utilisé ailleurs, par exemple un auditeur, vous pouvez utiliser une référence faible.

WeakHashMap peut être utilisé comme cache de courte durée des clés des données dérivées. Il peut également être utilisé pour conserver des informations sur les objets utilisés ailleurs et vous ne savez pas quand ces objets sont jetés.

Les références logicielles BTW sont comme des références faibles, mais elles ne seront pas toujours nettoyées immédiatement. Le GC supprimera toujours les références faibles quand il le pourra et conservera les références souples quand il le pourra.

Il existe un autre type de référence appelé référence fantôme. Ceci est utilisé dans le processus de nettoyage du GC et fait référence à un objet qui n'est pas accessible au code "normal" car il est en cours de nettoyage.

45
Peter Lawrey

Puisqu'une référence faible peut être réclamée par le ramasse-miettes à tout moment, y a-t-il une raison pratique de l'utiliser?

Bien sûr, il existe des raisons pratiques de l'utiliser. Il serait terriblement étrange que les concepteurs de framework fassent les frais énormes de la construction d'un système de référence faible qui était peu pratique, vous ne pensez pas?

Je pense que la question que vous aviez l'intention de poser était:

Quelles sont les situations réalistes dans lesquelles les gens utilisent des références faibles?

Il y a beaucoup de. Un objectif courant consiste à atteindre un objectif de performance. Lors de l'optimisation des performances d'une application, il faut souvent faire un compromis entre plus d'utilisation de la mémoire et plus de temps. Supposons par exemple qu'il existe un calcul complexe que vous devez effectuer plusieurs fois, mais le calcul est "pur" - la réponse ne dépend que des arguments, pas de l'état exogène. Vous pouvez créer un cache - une carte des arguments au résultat - mais qui utilise alors de la mémoire. Vous pourriez ne plus jamais poser la question, et cette mémoire serait alors gaspillée.

Des références faibles peuvent résoudre ce problème; le cache peut devenir assez volumineux, et donc du temps est économisé si la même question est posée plusieurs fois. Mais si le cache devient suffisamment grand pour que le garbage collector ait besoin de récupérer de l'espace, il peut le faire en toute sécurité.

L'inconvénient est bien sûr que la politique de nettoyage du garbage collector est réglée pour atteindre les objectifs de l'ensemble du système, pas votre problème de cache spécifique. Si la stratégie du GC et la stratégie de cache souhaitée sont suffisamment alignées, les références faibles sont une solution très pragmatique à ce problème.

29
Eric Lippert

Si une WeakReference est la référence uniquement à un objet, et que vous voulez que l’objet traîne, vous devriez probablement utiliser un SoftReference à la place.

Les références faibles sont mieux utilisées dans les cas où il y aura d'autres références à l'objet, mais vous ne pouvez pas (ou ne voulez pas avoir) détecter quand ces autres références ne sont plus utilisées. Ensuite, l'autre référence empêchera l'objet d'être récupéré, et la WeakReference ne sera qu'un autre moyen d'accéder au même objet.

Deux cas d'utilisation courants sont:

  1. Pour contenir des informations supplémentaires (souvent calculées de manière coûteuse mais reproductibles) sur des objets spécifiques que vous ne pouvez pas modifier directement et dont vous avez peu de contrôle sur le cycle de vie. WeakHashMap est un moyen parfait de conserver ces références: la clé dans le WeakHashMap n'est que faiblement détenue, et donc lorsque la clé est récupérée, la valeur peut également être supprimée de la carte, et donc être une ordure collectés.
  2. Pour implémenter une sorte de système d'événement ou de notification, où les "écouteurs" sont enregistrés auprès d'une sorte de coordinateur, afin qu'ils puissent être informés quand quelque chose se produit - mais où vous ne voulez pas empêcher ces auditeurs d'être récupérés lorsqu'ils viennent à la fin de leur vie. Un WeakReference pointera vers l'objet alors qu'il est encore vivant, mais pointera vers "null" une fois que l'objet d'origine aura été récupéré.
14
Bill Michell

Nous l'utilisons pour cette raison - dans notre exemple, nous avons une variété d'auditeurs qui doivent s'inscrire auprès d'un service. Le service conserve des références faibles aux écouteurs, tandis que les classes instanciées conservent des références fortes. Si les classes sont à tout moment GC'ed, la référence faible est tout ce qui reste des auditeurs, qui seront également GC'ed. Cela facilite beaucoup le suivi des classes intermédiaires.

12
Noah

L'utilisation la plus courante des références faibles concerne les valeurs dans les cartes de "recherche".

Avec des références de valeur normales (dures), si la valeur dans la carte n'a plus de références ailleurs, vous n'avez souvent plus besoin de la recherche. Avec des valeurs de carte faiblement référencées, une fois qu'il n'y a plus d'autres références, l'objet devient un candidat pour la récupération de place

Le fait que la carte elle-même ait une (seule) référence à l'objet ne l'empêche pas d'être récupéré car la référence est une référence faible

8
Bohemian

Pour éviter les fuites de mémoire, consultez ceci article pour plus de détails.

3
Óscar López

ne référence faible est une référence qui ne protège pas l'objet référent de la collecte par un garbage collector.

  • Un objet référencé uniquement par des références faibles est considéré comme inaccessible (ou "faiblement accessible") et peut donc être collecté à tout moment.
  • Des références faibles sont utilisées pour éviter de garder la mémoire référencée par des objets inutiles. Certains langages récupérés par les ordures comportent ou prennent en charge différents niveaux de références faibles, tels que Java, C #, Python, Perl ou LISP.
  • La récupération de place est utilisée pour réduire le risque de fuites de mémoire et de corruption de données. Il existe deux principaux types de récupération de place: le traçage et le comptage des références. Les schémas de comptage de références enregistrent le nombre de références à un objet donné et collectent l'objet lorsque le nombre de références devient nul. Le comptage de références ne peut pas collecter des références cycliques (ou circulaires) car un seul objet peut être collecté à la fois. Des groupes d'objets se référençant mutuellement qui ne sont pas directement référencés par d'autres objets et qui sont inaccessibles peuvent ainsi devenir résidents permanents; si une application génère continuellement de tels groupes d'objets inaccessibles, cela aura pour effet une fuite de mémoire. Des références faibles peuvent être utilisées pour résoudre le problème des références circulaires si les cycles de référence sont évités en utilisant des références faibles pour certaines des références du groupe.
  • Des références faibles sont également utilisées pour minimiser le nombre d'objets inutiles en mémoire en permettant au programme d'indiquer quels objets ne sont pas critiques en ne les référençant que faiblement.
3
Bhushan

Je l'utilise généralement pour certains types de cache. Les éléments récemment consultés sont disponibles immédiatement et en cas de manque de cache, vous rechargez l'élément (DB, FS, peu importe).

2
Jan Zyka

J'utilise WeakSet pour encoder les liens dans un graphique. Si un nœud est supprimé, les liens disparaissent automatiquement.

0
Neil G