web-dev-qa-db-fra.com

Java: différence entre référence forte / douce / faible / fantôme

J'ai lu cet article à propos du sujet, mais je ne le comprends pas vraiment. Donnez-moi des conseils, ainsi que des exemples pour décrire les concepts.

162
user1204873

Java fournit deux types/classes différents de Objets de référence: fort et faible . Les objets de référence faibles peuvent être divisés en doux et fantôme. Allons point par point.

Objet de référence fort

StringBuilder builder = new StringBuilder();

Il s'agit du type/de la classe d'objet de référence par défaut, sauf indication contraire: builder est un objet de référence puissant. Ce type de référence rend l'objet référencé non éligible pour GC. C'est-à-dire que lorsqu'un objet est référencé par un chaîne d'objets de référence puissants, il ne peut pas être récupéré.

Objet de référence faible

WeakReference<StringBuilder> weakBuilder = new WeakReference<StringBuilder>(builder);

Les objets de référence faibles ne sont pas le type/la classe par défaut de l'objet de référence et, pour être utilisés, ils doivent être explicitement spécifiés, comme dans l'exemple ci-dessus. Ce type de référence rend l'objet de référence éligible pour GC. En d’autres termes, si la seule référence accessible pour l’objet StringBuilder en mémoire est en fait la référence faible, le GC est autorisé à ordonner la récupération de l’objet StringBuilder. Lorsqu'un objet en mémoire n'est accessible que par des objets de référence faibles, il devient automatiquement éligible pour le GC.

Niveaux de faiblesse

Deux niveaux différents de faiblesse peuvent être utilisés: soft et fantôme.

Un objet de référence soft est fondamentalement un objet de référence faible qui reste un peu plus en mémoire: normalement, il résiste au cycle GC jusqu'à ce que la mémoire soit disponible et qu'il n'y ait aucun risque de OutOfMemoryError ( dans ce cas, il peut être enlevé).

D'autre part, un objet phantom Reference n'est utile que pour savoir exactement quand un objet a été supprimé de la mémoire: normalement, ils sont utilisés pour corriger weird finalize () revival/comportement de résurrection, puisqu'ils ne renvoient pas l'objet lui-même, mais seulement une aide en gardant une trace de leur présence dans la mémoire .

Les objets de référence faibles sont idéaux pour implémenter des modules de cache. En fait, une sorte d’expulsion automatique peut être mise en œuvre en permettant au CPG de nettoyer les zones de mémoire chaque fois que des objets/valeurs ne sont plus accessibles par une chaîne de références fortes. Un exemple est le WeakHashMap conserver les clés faibles.

129
Paolo Maresca

Référence faible:

En termes simples, une référence faible est une référence qui n'est pas assez forte pour forcer un objet à rester en mémoire. Les références faibles vous permettent de tirer parti de la capacité du ramasse-miettes de déterminer l'accessibilité pour vous, de sorte que vous n'avez pas à le faire vous-même.

Référence logicielle:

Une référence souple est exactement comme une référence faible, sauf qu'elle est moins encline à jeter l'objet auquel elle fait référence. Un objet qui n'est que faiblement accessible (les références les plus fortes en est WeakReferences) sera supprimé lors du prochain cycle de récupération de place, mais un objet qui sera doucement accessible restera généralement en place pendant un certain temps.

Référence du fantôme:

Une référence fantôme est assez différente de SoftReference ou de WeakReference. Son emprise sur son objet est tellement fragile que vous ne pouvez même pas le récupérer. Sa méthode get () renvoie toujours la valeur null. La seule utilisation d'une telle référence est de garder trace du moment où elle est mise en file d'attente dans une ReferenceQueue, car vous savez alors que l'objet sur lequel elle pointe est mort.

Ce texte a été extrait de: https://weblogs.Java.net/blog/2006/05/04/understanding-weak-references

72
Punith Raj

La simple différence entre SoftReference et WeakReference est fournie par développeur Android .

La différence entre SoftReference et WeakReference correspond au moment où la décision est prise d'effacer et de mettre en file d'attente la référence:

  • Un SoftReference doit être effacé et mis en file d'attente le plus tard possible, c'est-à-dire au cas où le VM risque de manquer de mémoire.

  • Un WeakReference peut être effacé et mis en file d'attente dès que l'on sait qu'il est faiblement référencé.

23

Les trois termes que vous avez utilisés sont principalement liés à l’éligibilité d’Object à se faire ramasser.

Référence faible :: C'est une référence qui n'est pas assez forte pour forcer l'objet à rester en mémoire. Ce sont les caprices du récupérateur de mémoire pour collecter cet objet pour la récupération de place. Vous ne pouvez pas forcer ce GC à ne pas le collecter .

Référence douce :: C'est plus ou moins la même chose que la référence faible. Mais vous pouvez dire qu'il maintient l'objet un peu plus fort que la référence faible de garbage collection.

Si les récupérateurs d'ordures collectent la référence faible au cours du premier cycle de vie, ils collecteront la référence souple au cours du prochain cycle de collecte des ordures.

Forte référence :: C'est juste l'opposé des deux types de références ci-dessus. Ils ressemblent moins à la collecte des ordures (la plupart du temps, ils ne sont jamais ramassés).

Vous pouvez vous référer au lien suivant pour plus d'informations:

http://docs.Oracle.com/javase/1.4.2/docs/api/Java/lang/ref/Reference.html

16
Sabya

4 degrés de référence - Strong, Weak, Soft, Phantom

Fort - est une sorte de référence qui rend l'objet référencé non éligible pour GC. classes de constructeur. par exemple - StringBuilder

Faible - est une référence éligible pour le GC.

Soft - est une sorte de référence dont l'objet est éligible pour GC jusqu'à ce que la mémoire soit disponible. Idéal pour le cache d'image. Il les tiendra jusqu'à ce que la mémoire soit disponible.

Phantom - est une sorte de référence dont l'objet est directement éligible pour le GC. Utilisé uniquement pour savoir quand un objet est supprimé de la mémoire.

les usages:

  1. Vous permet d'identifier quand un objet est supprimé de la mémoire.

  2. lorsque la méthode finalize() est surchargée, la GC peut ne pas se produire en temps voulu pour les objets éligibles pour la GC des deux classes. Donc, la référence fantôme les rend éligibles pour GC avant finalize(), c’est pourquoi vous pouvez obtenir OutOfMemoryErrors même lorsque la majeure partie du tas est inutilisable.

Les références faibles sont idéales pour implémenter les modules de cache.

10
Preetham R U

Ceci article peut être très utile pour comprendre les références fortes, douces, faibles et fantômes.


Pour vous donner un résumé,

Si vous avez une référence forte à un objet, cet objet ne peut jamais être collecté/récupéré par GC (Garbage Collector).

Si vous avez uniquement de faibles références à un objet (sans références fortes), l'objet sera récupéré par GC au cours du prochain cycle de GC.

Si vous avez uniquement des références souples à un objet (sans références fortes), l'objet ne sera récupéré par GC que lorsque la JVM sera à court de mémoire.

Nous créons des références fantômes à un objet pour garder une trace de la mise en file d'attente de l'objet dans le ReferenceQueue. Une fois que vous savez que vous pouvez effectuer une finalisation fine. (Cela vous éviterait de ressusciter accidentellement l'objet car la référence fantôme ne vous donne pas le référent). Je vous conseillerais de lire this article pour en savoir plus sur ce sujet.


Vous pouvez donc dire que les références fortes ont le pouvoir ultime (ne peut jamais être collecté par GC)

Les références logicielles sont puissantes que les références faibles (car elles peuvent échapper au cycle GC jusqu'à ce que la JVM manque de mémoire)

Les références faibles sont encore moins puissantes que les références souples (car elles ne peuvent échapper à aucun cycle GC et seront récupérées si l'objet n'a pas d'autre référence forte).


Analogie avec les restaurants

  • Serveur - GC
  • You - Objet en tas
  • Zone de restauration/espace - Heap Space
  • Nouveau client - Nouvel objet qui veut une table dans un restaurant

Maintenant, si vous êtes un client fort (analogue à une référence forte), alors même si un nouveau client arrive dans le restaurant ou peu importe ce qui se passe, vous ne quitterez jamais votre table tas). Le serveur n'a pas le droit de vous dire (ou même de vous demander) de quitter le restaurant.

Si vous êtes un client léger (analogue à une référence virtuelle), alors si un nouveau client arrive au restaurant, le serveur ne vous demandera pas de quitter la table à moins qu'il ne reste plus de table vide. accueillir le nouveau client. (En d'autres termes, le serveur vous demandera de ne quitter la table que si un nouveau client arrive et qu'il ne reste plus de table pour ce nouveau client)

Si vous êtes un client faible (analogue à une référence faible), le serveur peut alors, à sa volonté, vous demander (à tout moment) de vous demander de quitter le restaurant: P

5
Lavish Kothari

Références fortes

Ce sont vos références d'objet habituelles que nous codons quotidiennement:

Employee emp = new Employee();

La variable "emp" contient une référence forte à un objet Employé et les objets accessibles via n'importe quelle chaîne de références fortes ne sont pas éligibles pour le nettoyage de la mémoire. Habituellement, c'est ce que vous voulez, mais pas toujours. Supposons maintenant que nous récupérons beaucoup d'employés de la base de données dans une collection ou une carte, et que nous devons effectuer beaucoup de traitements sur eux régulièrement. Ainsi, afin de préserver les performances, nous les garderons dans le cache.

Dans la mesure où cela est bon, nous avons maintenant besoin de données différentes et nous n’avons pas besoin de ces objets Employee, qui ne sont référencés nulle part ailleurs que dans le cache. Ce qui provoque une fuite de mémoire parce que ces objets ne sont pas utilisés mais ne sont toujours pas éligibles pour le garbage collection et que nous ne pouvons pas les supprimer du cache car nous n’avons aucune référence à ces objets. Donc ici, soit nous devons vider manuellement tout le cache, ce qui est fastidieux, ou nous pourrions utiliser d’autres types de références, par exemple. Références faibles.

Références faibles

Une référence faible n'épingle pas un objet dans la mémoire et sera récupérée par GC lors du prochain cycle GC si elle n'est pas référencée à partir d'autres références. Nous pouvons utiliser la classe WeakReference fournie par Java pour créer le type de cache ci-dessus, qui ne stockera pas les objets qui ne sont pas référencés ailleurs.

WeakReference<Cache> cache = new WeakReference<Cache>(data);

Pour accéder aux données, vous devez appeler cache.get (). Cet appel à get peut renvoyer la valeur null si la référence faible a été récupérée: vous devez vérifier la valeur renvoyée pour éviter les NPE. Java fournit des collections qui utilisent des références faibles, par exemple, la classe WeakHashMap stocke les clés (et non les valeurs) comme des références faibles. Si la clé est GC’d, la valeur sera automatiquement supprimée de la carte.

Etant donné que les références faibles sont aussi des objets, nous avons besoin d’un moyen de les nettoyer (elles ne sont plus utiles lorsque l’objet référencé a été GC). Si vous transmettez une référenceQueue au constructeur pour une référence faible, le récupérateur de place ajoutera cette référence faible à la classe ReferenceQueue avant qu'elle ne soit finalisée ou que GC'd. Vous pouvez traiter périodiquement cette file d'attente et traiter les références mortes.

Références molles

Un SoftReference est comme un WeakReference, mais il est moins susceptible d'être ramassé. Les références logicielles sont effacées à la discrétion du ramasse-miettes en réponse à la demande de mémoire. La machine virtuelle garantit que toutes les références logicielles à des objets facilement accessibles auront été effacées avant de générer une erreur OutOfMemoryError.

Références fantômes

Les références fantômes sont les plus faibles de tous les types de références; appeler sur elles renverra toujours la valeur null. Un objet est référencé de manière fantomatique après sa finalisation, mais avant que sa mémoire allouée ait été récupérée. Par opposition aux références faibles qui sont mises en file d'attente avant leur finalisation ou lorsque les références GC's Phantom sont rarement utilisées.

Alors, comment sont-ils utiles? Lorsque vous construisez une référence fantôme, vous devez toujours transmettre une référenceQueue. Cela indique que vous pouvez utiliser une référence fantôme pour voir quand votre objet est GC’d.

Alors, si les références faibles sont mises en file d'attente lorsqu'elles sont considérées comme étant en cours de finalisation mais pas encore par GC, nous pourrions créer une nouvelle référence forte pour l'objet dans le bloc de finaliseur et éviter que l'objet ne soit plus par GC. Oui, vous pouvez, mais vous ne devriez probablement pas faire cela. Pour vérifier ce cas, le cycle GC se produira au moins deux fois pour chaque objet, à moins que cet objet ne soit accessible que par une référence fantôme. C'est pourquoi vous pouvez manquer de mémoire même lorsque votre mémoire contient beaucoup de déchets. Les références fantômes peuvent empêcher cela.

Vous pouvez en lire plus sur mon article Types de références en Java (Fort, Doux, Faible, Fantôme) .

5
Naresh Joshi