J'ai lu cet article sur le sujet, mais je ne le comprends pas vraiment. Veuillez me donner quelques conseils et des exemples pour décrire les concepts.
J'ai lu cet article sur le sujet, mais je ne le comprends pas vraiment. Veuillez me donner quelques conseils et des exemples pour décrire les concepts.
Réponses:
Java fournit deux types / classes d' objets de référence différents : fort et faible . Les objets de référence faibles peuvent être divisés en objets souples et fantômes .
Allons-y point par point.
Objet de référence fort
StringBuilder builder = new StringBuilder();
Il s'agit du type / classe par défaut de l'objet de référence, s'il n'est pas spécifié différemment: builder
est un objet de référence fort. Ce type de référence rend l'objet référencé non éligible pour GC. Autrement dit, chaque fois qu'un objet est référencé par une chaîne d'objets de référence forts , 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 / classe d'objet de référence par défaut 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. Autrement dit, dans le cas où la seule référence accessible pour l' StringBuilder
objet en mémoire est, en fait, la référence faible, alors le GC est autorisé à ramasser l' StringBuilder
objet. Lorsqu'un objet en mémoire est accessible uniquement par des objets de référence faibles, il devient automatiquement éligible pour GC.
Niveaux de faiblesse
Deux niveaux différents de faiblesse peuvent être enrôlés: doux et fantôme .
Un objet de référence souple 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 qu'aucune mémoire ne soit disponible et qu'il y ait un risque de OutOfMemoryError
(dans ce cas, il peut être supprimé).
D'un autre côté, un objet de référence fantôme n'est utile que pour savoir exactement quand un objet a été effectivement supprimé de la mémoire: normalement, ils sont utilisés pour corriger le comportement étrange de revival / résurrection de finalize () , car ils ne renvoient pas l'objet lui-même mais seulement aider à garder 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'éviction automatique peut être mise en œuvre en permettant au GC de nettoyer les zones mémoire chaque fois que les objets / valeurs ne sont plus accessibles par une chaîne de références forte. Un exemple est le WeakHashMap conservant des clés faibles.
strongRef --> weakRef --> objA
. Maintenant, sera objA
GC ou non, car il a une référence indirecte de strongRef
.
Référence faible:
Une référence faible, en termes simples, 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 garbage collector à déterminer l'accessibilité pour vous, vous n'avez donc pas à le faire vous-même.
Référence souple:
Une référence souple est exactement comme une référence faible, sauf qu'elle est moins désireuse de jeter l'objet auquel elle se réfère. Un objet qui n'est que faiblement accessible (les références les plus fortes sont WeakReferences) sera ignoré au prochain cycle de garbage collection, mais un objet qui est facilement accessible restera généralement pendant un certain temps.
Référence fantôme:
Une référence fantôme est assez différente de SoftReference ou WeakReference. Son emprise sur son objet est si ténue que vous ne pouvez même pas récupérer l'objet - sa méthode get () renvoie toujours null. La seule utilité d'une telle référence est de garder une trace du moment où elle est mise en file d'attente dans une ReferenceQueue, car à ce stade, vous savez que l'objet vers lequel il pointait est mort.
Ce texte a été extrait de: https://weblogs.java.net/blog/2006/05/04/understanding-weak-references
La simple différence entre SoftReference
et WeakReference
est fournie par Android Developer .
La différence entre a SoftReference
et a WeakReference
est le moment auquel la décision est prise d'effacer et de mettre la référence en file d'attente:
A SoftReference
doit être effacé et mis en file d'attente le plus tard possible, c'est-à-dire au cas où la machine virtuelle risque de manquer de mémoire.
A WeakReference
peut être effacé et mis en file d'attente dès que l'on sait qu'il est faiblement référencé.
Cet 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, alors l'objet ne peut jamais être collecté / récupéré par GC (Garbage Collector).
Si vous n'avez que des références faibles à un objet (sans références fortes), alors l'objet sera récupéré par GC au tout prochain cycle GC.
Si vous avez seulement des références logicielles à 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 suivre le moment où l'objet est mis en file d'attente 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 suggère de lire cet article pour obtenir des détails détaillés à ce sujet.
Vous pouvez donc dire que les références fortes ont un pouvoir ultime (ne peuvent jamais être collectées par GC)
Les références souples sont puissantes que les références faibles (car elles peuvent échapper au cycle GC jusqu'à ce que JVM soit à court 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 de restaurant
Maintenant, si vous êtes un client solide (analogue à une référence forte), alors même si un nouveau client arrive au restaurant ou quoi que ce soit d'autre, vous ne quitterez jamais votre table (la zone de mémoire en tas). Le serveur n'a pas le droit de vous dire (ni même de vous demander) de quitter le restaurant.
Si vous êtes un client doux (analogue à soft reference), alors si un nouveau client arrive au restaurant, le serveur ne vous demandera pas de quitter la table à moins qu'il ne reste plus d'autre table vide pour accueillir le nouveau client. (En d'autres termes, le serveur vous demandera de quitter la table uniquement si un nouveau client entre et qu'il n'y a plus d'autre table pour ce nouveau client)
Si vous êtes un client faible (analogue à une référence faible), le serveur, à sa guise, peut (à tout moment) vous demander de quitter le restaurant: P
Les trois termes que vous avez utilisés sont principalement liés à l'éligibilité d'Object à la récupération de la mémoire.
Référence faible : c'est une référence qui n'est pas assez forte pour forcer l'objet à rester en mémoire. C'est le caprice du garbage collector de collecter cet objet pour le garbage collection. Vous ne pouvez pas forcer ce GC à ne pas le récupérer .
Référence souple : C'est plus ou moins la même chose que la référence faible. Mais vous pouvez dire qu'il contient l'objet un peu plus fortement que la référence faible du garbage collection.
Si les garbage collector collectent la référence faible dans le premier cycle de vie lui-même, ils collecteront la référence logicielle dans le prochain cycle de garbage collection.
Référence forte : C'est juste le contraire des deux types de références ci-dessus. Ils ressemblent moins à la collecte des déchets (la plupart du temps, ils ne sont jamais collecté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
Voici vos références d'objets habituelles que nous codons quotidiennement:
Employee emp = new Employee();
La variable «emp» contient une référence forte à un objet Employee et les objets qui sont accessibles via n'importe quelle chaîne de références fortes ne sont pas éligibles pour le garbage collection. Habituellement, c'est ce que vous voulez mais pas toujours. Supposons maintenant que nous récupérions beaucoup d'employés de la base de données dans une collection ou une carte, et que nous devions faire beaucoup de traitement sur eux régulièrement, donc pour maintenir les performances, nous les garderons dans le cache.
Dans la mesure où cela est bon, mais maintenant nous avons besoin de données différentes et nous n'avons pas besoin de ces objets Employee et ceux-ci ne sont référencés de nulle part sauf du cache. Ce qui provoque une fuite de mémoire car ces objets ne sont pas utilisés mais ne sont toujours pas éligibles pour le garbage collection et nous ne pouvons pas supprimer ces objets du cache car nous n'avons pas de référence à eux? Donc ici, soit nous devons vider tout le cache manuellement, ce qui est fastidieux, soit nous pourrions utiliser d'autres références de type, par exemple des références faibles.
Une référence faible n'épingle pas un objet en mémoire et sera GC dans le prochain cycle GC si elle n'est pas référencée à partir d'autres références. Nous pouvons utiliser la classe WeakReference qui est fournie par Java pour créer le type de caches 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 null si la référence faible a été récupérée: vous devez vérifier la valeur retournée pour éviter les NPE. Java fournit des collections qui utilisent des références faibles, par exemple, la classe WeakHashMap stocke des clés (et non des valeurs) comme des références faibles. Si la clé est GC, la valeur sera également automatiquement supprimée de la carte.
Puisque 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 qu'elles référençaient a été GC). Si vous passez un ReferenceQueue au constructeur pour une référence faible, le garbage collector ajoutera cette référence faible à ReferenceQueue avant qu'ils ne soient finalisés ou GC. Vous pouvez périodiquement traiter cette file d'attente et traiter les références mortes.
Un SoftReference est comme un WeakReference mais il est moins susceptible d'être ramassé. Les références souples sont effacées à la discrétion du garbage collector en réponse à la demande de mémoire. La machine virtuelle garantit que toutes les références logicielles à des objets accessibles en douceur auront été effacées avant de lancer une erreur OutOfMemoryError.
Les références fantômes sont les plus faibles de tous les types de références, appeler get sur elles renverra toujours null. Un objet est référencé de manière fantôme après avoir été finalisé, mais avant que sa mémoire allouée n'ait été récupérée, contrairement aux références faibles qui sont mises en file d'attente avant d'être finalisées ou les références fantômes GC sont rarement utilisées.
Alors, comment sont-ils utiles? Lorsque vous construisez une référence fantôme, vous devez toujours passer une ReferenceQueue. Cela indique que vous pouvez utiliser une référence fantôme pour voir quand votre objet est GC.
Hé, donc si des références faibles sont mises en file d'attente lorsqu'elles sont considérées comme finalisées mais pas encore GC, nous pourrions créer une nouvelle référence forte à l'objet dans le bloc du finaliseur et empêcher l'objet d'être 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 tas même si 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 (Strong, Soft, Weak, Phantom) .
4 degrés de référence - Strong, Weak, Soft, Phantom
Strong - est une sorte de référence, ce qui rend l'objet référencé non éligible pour GC. classes de constructeur. par exemple - StringBuilder
Faible - est une référence qui est éligible pour 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 conservera jusqu'à ce que la mémoire soit disponible.
Phantom - est une sorte de référence dont l'objet est directement éligible pour GC. Utilisé uniquement pour savoir quand un objet est supprimé de la mémoire.
les usages:
Vous permet d'identifier quand un objet est exactement supprimé de la mémoire.
lorsque la
finalize()
méthode est surchargée, GC peut ne pas se produire en temps opportun pour les objets éligibles GC des deux classes. Donc, la référence fantôme les rend éligibles pour GC avantfinalize()
, c'est pourquoi vous pouvez obtenir OutOfMemoryErrors même lorsque la plupart du tas est des ordures.
Les références faibles sont idéales pour implémenter les modules de cache.