J'ai lu cet article sur les différents types de références en Java (forte, douce, faible, fantôme), mais je ne le comprends pas vraiment.
Quelle est la différence entre ces types de références et quand chaque type serait-il utilisé ?
J'ai lu cet article sur les différents types de références en Java (forte, douce, faible, fantôme), mais je ne le comprends pas vraiment.
Quelle est la différence entre ces types de références et quand chaque type serait-il utilisé ?
Java propose deux types/classes différents d'Objets de Référence : forte et faible. Les Objets de Référence Faible peuvent être encore divisés en soft et phantom.
Allons point par point.
Objet de Référence Forte
StringBuilder builder = new StringBuilder();
Il s'agit du type/classe par défaut d'Objet de Référence, sauf indication contraire : builder
est un Objet de Référence Forte. Ce genre de référence rend l'objet référencé non éligible à la GC. C'est-à-dire, 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 collecté par le ramasse-miettes.
Objet de Référence Faible
WeakReference weakBuilder = new WeakReference(builder);
Les Objets de Référence Faible ne sont pas le type/classe par défaut d'Objet de Référence et pour les utiliser, ils doivent être explicitement spécifiés comme dans l'exemple ci-dessus. Ce genre de référence rend l'objet de référence éligible à la GC. C'est-à-dire, au cas où la seule référence accessible pour l'objet StringBuilder
en mémoire est, en fait, la référence faible, alors le ramasse-miettes est autorisé à collecter l'objet StringBuilder
. Lorsqu'un objet en mémoire est accessible uniquement par des Objets de Référence Faible, il devient automatiquement éligible à la GC.
Niveaux de Faiblesse
Deux différents niveaux de faiblesse peuvent être répertoriés : soft et phantom.
Un Objet de Référence soft est essentiellement un Objet de Référence Faible qui reste un peu plus longtemps en mémoire : normalement, il résiste au cycle de la GC jusqu'à ce qu'aucune mémoire ne soit disponible et il y a un risque d'OutOfMemoryError
(dans ce cas, il peut être supprimé).
En revanche, un Objet de Référence phantom est utile seulement pour savoir exactement quand un objet a été effectivement supprimé de la mémoire : en général, ils sont utilisés pour corriger un comportement de résurrection étrange de finalize(), car ils ne retournent en réalité pas l'objet lui-même mais aident simplement à suivre leur présence en mémoire.
Les Objets de Référence Faible sont idéaux pour mettre en œuvre des modules de cache. En effet, une sorte d'éviction automatique peut être mise en œuvre en permettant au GC de nettoyer les zones de mémoire chaque fois que les objets/valeurs ne sont plus accessibles par une chaîne de références fortes. Un exemple est le WeakHashMap conservant des clés faibles.
Référence Faible :
Une référence faible, simplement dit, 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 collecteur d'ordures à déterminer la portée pour vous, afin que vous n'ayez 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 encline à jeter l'objet auquel elle se réfère. Un objet qui est seulement faiblement atteignable (les références les plus fortes à lui sont WeakReferences) sera jeté lors du prochain cycle de collecte des ordures, mais un objet qui est doucement atteignable restera généralement un moment.
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énu que vous ne pouvez même pas retrouver l'objet - sa méthode get() renvoie toujours null. La seule utilisation d'une telle référence est de suivre quand elle est mise en file d'attente dans une ReferenceQueue, à ce moment-là, vous savez que l'objet auquel elle pointait est mort.
Ce texte a été extrait de: https://weblogs.java.net/blog/2006/05/04/understanding-weak-references
Bien que tout dans cette réponse semble correct, il me semble également qu'il peut y avoir une erreur sur la page web liée. Le Javadoc pour le package java.lang.ref et celui pour PhantomReference suggèrent qu'un objet n'est pas ramassé par le ramasse-miettes tant qu'il n'est plus "phantom reachable", ce qui implique que (contrairement à SoftReference) une PhantomReference doit être détrée avant que l'objet auquel elle fait référence ne soit ramassé par le ramasse-miettes...et son enfilement ne signale pas que la mémoire associée a été libérée.
@TheodoreMurdock La javadoc est correcte. Une référence fantôme n'empêche pas du tout la collecte des ordures. Une fois qu'un objet est mis en file d'attente, il ne peut plus être sauvegardé même par un finaliseur, car les finaliseurs ont déjà été exécutés. Il est mort, mais pas encore parti.
La simple différence entre SoftReference
et WeakReference
est fournie par Android Developer.
La différence entre un SoftReference
et un WeakReference
est le moment où la décision de nettoyer et mettre en file d'attente la référence est prise :
Un SoftReference
devrait être nettoyé et mis en file d'attente le plus tard possible, c'est-à-dire lorsque la VM est en danger de manquer de mémoire.
Un WeakReference
peut être nettoyé et mis en file d'attente dès lors qu'il est connu 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 le 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 le GC dès le prochain cycle de GC.
Si vous n'avez que des références souples à un objet (sans références fortes), alors l'objet sera récupéré par le GC seulement lorsque le JVM manque de mémoire.
Nous créons des références fantômes à un objet pour suivre quand l'objet est mis en file d'attente dans la ReferenceQueue
. Une fois que vous savez cela, vous pouvez effectuer une finalisation fine. (Cela vous éviterait de ressusciter accidentellement l'objet car les références fantômes ne vous donnent pas le référent). Je vous suggère de lire cet article pour obtenir des détails approfondis à ce sujet.
Vous pouvez donc dire que les références fortes ont un pouvoir ultime (ne peuvent jamais être collectées par le GC)
Les références souples sont puissantes que les références faibles (car elles peuvent échapper au cycle du GC jusqu'à ce que le 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 de GC et seront récupérées si l'objet n'a aucune autre référence forte).
Analogie de restaurant
Maintenant, si vous êtes un client fort (analogique à une référence forte), alors même si un nouveau client arrive au restaurant ou quoi qu'il arrive, vous ne quitterez jamais votre table (la zone mémoire sur le 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 mou (analogue à une référence souple), alors si un nouveau client arrive au restaurant, le serveur ne vous demandera pas de quitter la table sauf s'il n'y a plus d'autres tables vides pour accueillir le nouveau client. (En d'autres termes, le serveur vous demandera de quitter la table seulement 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), alors 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é de l'objet à être collecté par le ramasse-miettes.
Référence faible :: C'est une référence qui n'est pas assez forte pour empêcher l'objet de rester en mémoire. C'est le caprice du ramasse-miettes de collecter cet objet pour le ramassage des ordures. Vous ne pouvez pas forcer le GC à ne pas le collecter.
Référence douce :: C'est plus ou moins similaire à la référence faible. Mais vous pouvez dire qu'elle retient un peu plus fermement l'objet que la référence faible lors de la collecte des ordures.
Si les collecteurs d'ordures collectent la référence faible dès le premier cycle de vie, ils collecteront la référence douce dans le cycle suivant de la collecte des ordures.
Référence forte :: C'est exactement l'opposé des deux types de références mentionnés ci-dessus. Ils sont moins susceptibles d'être collectés par le ramasse-miettes (la plupart du temps, ils ne le sont jamais).
Vous pouvez consulter le lien suivant pour plus d'informations :
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ref/Reference.html
Je pense que ceci est faux - "Si les collecteurs de déchets ramassent la référence faible dès le premier cycle de vie, ils collecteront la référence molle lors du cycle suivant de la collecte des déchets." Ce n'est pas nécessairement ainsi, comment pouvez-vous être si sûr qu'ils se produisent dans des exécutions consécutives de GC ? GC peut permettre aux objets référencés faiblement de survivre même lors du 2ème et 3ème cycle. Il n'y a pas de documentation à ce sujet, s'il y en a une alors veuillez mentionner le lien spécifiant.
Aussi, votre réponse est un peu vague, regardez cette phrase 'C'est plus ou moins la même chose que la référence faible. Mais vous pouvez dire qu'elle retient l'objet un peu plus fortement que la référence faible de la collecte des déchets.' - il demande clairement la différence et non les similitudes, tous ces mots ajoutent plus de confusion que de clarté sur le sujet.
@SaurabhPatil -- J'ai manqué votre commentaire. Voici les réponses. 1. "il demande clairement la différence et non les similitudes" -- Référez-vous à la description de la question (pas seulement le titre) "S'il vous plaît, donnez-moi des conseils et donnez-moi des exemples pour expliquer". 2. "Mais vous pouvez dire que cela retient un peu plus l'objet ...." Je pense que SOF donne la possibilité de voter négativement et de donner de nouvelles réponses aussi.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
2 votes
weblogs.java.net/blog/2006/05/04/understanding-weak-references
4 votes
J'ai lu ce document, il ne m'aide pas à imaginer quelle différence. (peut-être parce que c'est un document difficile à lire)
16 votes
Si vous avez lu cet article et que vous ne comprenez toujours pas, avez-vous des questions spécifiques à ce sujet? Il est difficile de répondre à "S'il vous plaît, expliquez-moi Foo", "Voici ce que cela signifie", "Je ne comprends pas" sans précisions sur les parties que vous ne comprenez pas.
4 votes
Possible duplicate de Comprendre les classes de référence de Java : SoftReference, WeakReference et PhantomReference
1 votes
@LouisWasserman Le lien en haut n'est plus valide.
0 votes
Ajout à la question:
strongRef --> weakRef --> objA
. Maintenant, est-ce queobjA
sera GCed ou non, car il a une référence indirecte destrongRef
.0 votes
Est-ce que cette réponse répond à votre question? Compréhension des classes de référence en Java : SoftReference, WeakReference et PhantomReference