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

Duplication possible:
Références faibles – Quelle est leur utilité?

Comme les références faibles peuvent être revendiquées par le ramasse-miettes à tout moment, existe-t-il une raison pratique de les utiliser?

Si vous voulez garder 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 pour les données dérivées. Il peut également être utilisé pour conserver des informations sur les objects utilisés ailleurs et vous ne savez pas quand ces objects sont supprimés.

BTW Soft References est comme des références faibles, mais elles ne seront pas toujours nettoyées immédiatement. Le CPG rejettera toujours les références faibles quand il le peut et conservera les références souples le cas échéant.

Il existe un autre type de référence appelé référence fantôme. Ceci est utilisé dans le processus de nettoyage GC et fait référence à un object qui n’est pas accessible au code “normal” car il est en train d’être nettoyé.

Comme la référence faible peut être revendiquée à tout moment par le garbage collector, existe-t-il une raison pratique de l’utiliser?

Bien sûr, il y a des raisons pratiques de l’utiliser. Ce serait terriblement étrange si les concepteurs de framework étaient confrontés à l’énorme coût de la construction d’un système de référence faible et peu pratique , ne pensez-vous pas?

Je pense que la question que vous avez voulu poser était:

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

Il y a beaucoup de. Un objective commun est d’atteindre un objective de performance. Lors de l’optimisation des performances d’une application, il faut souvent faire un compromis entre une utilisation accrue de la mémoire et une utilisation plus rapide du temps. Supposons, par exemple, qu’il y ait un calcul complexe que vous devez effectuer plusieurs fois, mais le calcul est «pur» – la réponse dépend uniquement des arguments et non de l’état exogène. Vous pouvez créer un cache – une carte à partir des arguments au résultat – mais qui utilise alors 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 éventuellement résoudre ce problème; le cache peut devenir assez volumineux et, par conséquent, le temps est sauvegardé si la même question est posée plusieurs fois. Mais si le cache devient suffisamment volumineux pour que le ramasse-miettes puisse 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 ramasse-miettes est adaptée aux objectives de l’ensemble du système, et non à votre problème de cache spécifique. Si la politique du GC et la politique de cache souhaitée sont suffisamment alignées, les références faibles constituent une solution très pragmatique à ce problème.

Si une référence WeakReference est la seule référence à un object, et que vous voulez que l’object rest en attente , vous devriez probablement utiliser plutôt une SoftReference .

WeakReferences sont mieux utilisés dans les cas où il y aura d’autres références à l’object, mais vous ne pouvez pas (ou ne voulez pas avoir à le faire) détecter quand ces autres références ne sont plus utilisées. Ensuite, l’ autre référence empêchera l’object d’être récupéré, et la référence WeakRefer sera simplement un autre moyen d’accéder au même object.

Deux cas d’utilisation courants sont:

  1. Pour conserver des informations supplémentaires (souvent coûteuses mais reproductibles) sur des objects 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 idéal de conserver ces références: la clé dans WeakHashMap n’est que faiblement contenue, et donc, lorsque la clé est remplie, la valeur peut également être supprimée de la carte et donc être nettoyée.
  2. Pour implémenter une sorte de système de notification ou d’événement, où les “écouteurs” sont enregistrés avec une sorte de coordinateur, ils peuvent être informés quand quelque chose se produit, mais où vous ne voulez pas empêcher ces auditeurs la fin de leur vie. Un WeakReference pointera sur l’object alors qu’il est encore en vie, mais pointez sur “null” une fois que l’object d’origine a été collecté.

Nous l’utilisons pour cette raison – dans notre exemple, nous avons une variété d’auditeurs qui doivent s’inscrire à un service. Le service garde des références faibles aux écouteurs, tandis que les classes instanciées conservent des références fortes. Si les classes à un moment donné sont GC’ed, la référence faible est tout ce qui rest des auditeurs, qui seront alors aussi GC. Cela facilite grandement le suivi des classes intermédiaires.

L’utilisation la plus courante des références faibles concerne les valeurs dans les cartes de “recherche”.

Avec des références de valeurs normales (difficiles), si la valeur de la carte ne contient 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’object devient candidat à la récupération de mémoire

Le fait que la carte elle-même ait une (seule) référence à l’object ne l’empêche pas d’être collectée parce que la référence est une référence faible

Pour éviter les memory leaks, consultez cet article pour plus de détails.

Une référence faible est une référence qui ne protège pas l’object référent de la collecte par un ramasse-miettes.

  • Un object 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.
  • Les références faibles permettent d’éviter de conserver la mémoire référencée par des objects inutiles. Certains langages collectés présentent des 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 les risques de fuite de mémoire et de corruption de données. Il existe deux principaux types de nettoyage de la mémoire: le traçage et le comptage de références. Les schémas de comptage de référence enregistrent le nombre de références à un object donné et collectent l’object lorsque le compte de référence devient nul. Le comptage des références ne peut pas collecter de références cycliques (ou circulaires) car un seul object peut être collecté à la fois. Les groupes d’objects faisant référence mutuellement qui ne sont pas directement référencés par d’autres objects et sont inaccessibles peuvent ainsi devenir résidents permanents; Si une application génère continuellement de tels groupes d’objects 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.
  • Les références faibles sont également utilisées pour minimiser le nombre d’objects inutiles en mémoire en permettant au programme d’indiquer quels objects ne sont pas critiques en les référençant faiblement.

Je l’utilise généralement pour un certain type de cache. Les éléments récemment accédés sont disponibles immédiatement et en cas d’échec du cache, vous rechargez l’élément (DB, FS, etc.).

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