Quelle est la différence entre SoftReference et WeakReference en Java?

quelle différence?   

703
demandé sur Pacerier 2008-11-18 21:26:37

12 réponses

à Partir de la Compréhension des Références Faibles , par Ethan Nicolas:

références faibles

A faible référence , simplement dit, est un 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 la capacité de l'éboueur à déterminer l'accessibilité pour vous, alors vous n'avez pas à le faire m'. Vous créer une référence faible comme ceci:

WeakReference weakWidget = new WeakReference(widget);

et puis ailleurs dans le code, vous pouvez utiliser weakWidget.get() pour obtenir le réel Widget objet. Bien sûr, la faiblesse de l' la référence n'est pas assez fort pour empêcher la collecte des ordures, de sorte que vous pouvez trouver (si il n'y a pas fort références au widget) que weakWidget.get() commence soudainement le retour "à la 151940920" .

...

Doux références

Un doux "la référence 1519190920", c'est exactement comme un référence faible, sauf qu'il est moins désireux de jeter l'objet d' auxquels il se réfère. Un objet qui est seulement faiblement accessible (la plus forte références sont WeakReferences ) seront jetés à la prochaine poubelle cycle de collecte, mais un objet qui est doucement accessible généralement rester dans les parages pendant un certain temps.

SoftReferences ne sont pas nécessaire se comporter différemment WeakReferences , mais dans la pratique, doucement accessible objets sont généralement conservés aussi longtemps que la mémoire est en approvisionnement abondant. Cela fait d'eux une excellente base pour une cache, tels comme le cache d'image décrit ci-dessus, puisque tu peux laisser les ordures collecteur de vous soucier de combien accessible les objets sont (fortement objet accessible sera jamais être retiré de la cache) et à quel point il en a besoin le mémoire qu'ils consomment.

et Peter Kessler ajouté dans un commentaire:

le Sun JRE ne traite pas les différences légères différemment. Nous essayons de maintenir l'objet référencé par une référence douce s'il n'y a pas de pression sur la mémoire disponible. Un détail: les règles pour les JRE "-client" et "-serveur" sont différentes: - le client JRE essaie de garder votre empreinte en préférant Effacer les différences de type SoftReferences plutôt que d'étendre le tas, tandis que le serveur JRE essaie de garder vos performances élevées en préférant étendre le tas (si possible) plutôt que d'Effacer les différences de type SoftReferences. Une seule taille ne convient pas à tous.

824
répondu Michael Myers 2017-08-11 18:37:20

les références faibles sont recueillies avec empressement. Si le GC constate qu'un objet est peu accessible (accessible seulement par de faibles références), il va effacer les de faibles références à cet objet immédiatement. En tant que tels, ils sont bons pour garder une référence à un objet pour lequel votre programme conserve également (fortement référencé) "information associée" quelque part, comme en cache la réflexion de l'information à propos d'une classe, ou un wrapper pour un objet, etc. Tout ce qui n'a pas de sens de garder après l'objet, il est associé avec est GC-ed. Lorsque la référence faible est effacée, il est interrogé dans un référence queue que vos sondages de code quelque part, et il écarte la les objets associés. C'est-à-dire, vous gardez des informations supplémentaires sur un objet, mais cette information n'est pas nécessaire une fois l'objet auquel elle se réfère disparaître. En fait, dans certaines situations, vous pouvez même WeakReference et garder les informations supplémentaires associées sur l'objet dans les domaines de la sous-classe WeakReference. Un autre type l'utilisation de WeakReference est en conjonction avec Maps pour conserver les instances canoniques.

SoftReferences d'autre part, sont bonnes pour la mise en cache externe, recreatable ressources comme le GC retarde habituellement leur dédouanement. Il est garanti cependant que tous Sofretreferences seront éliminés avant Outofmoryerror est lancé, de sorte qu'ils théoriquement, ne peut pas causer un OOME [*].

exemple de cas D'utilisation Type: fichier. Vous feriez implémenter un système où vous chargeriez un fichier, le parserait et le conserveriez une référence à L'objet racine de la représentation parsée. La prochaine fois vous avez besoin du fichier, vous essaierez de le récupérer par le biais de la SoftReference. Si vous pouvez le récupérer, vous avez épargné vous-même un autre chargement/analyse, et si le GC effacé en attendant, vous le recharger. De cette façon, vous utilisez libre mémoire pour l'optimisation des performances, mais ne prenez pas de risque.

Maintenant, pour le [*]. Garder une référence douce ne peut pas causer un OOME en lui-même. Si d'un autre côté vous utilisez par erreur SoftReference pour une tâche une faible référence est destinée à utiliser (à savoir, vous conservez des informations associées à un objet d'une manière ou d'une autre fortement référencé, et le jeter lorsque l'objet de Référence obtient cleared), vous pouvez tomber sur OOME comme votre code qui scrute la ReferenceQueue et les rejets les objets associés pourraient arriver à ne pas fonctionner dans un temps mode.

Ainsi, la décision dépend de l'utilisation - si vous êtes à la mise en cache l'information est coûteuse à construire, mais néanmoins reconstituable à partir d'autres données, Utiliser des références douces - si vous gardez une référence à une instance canonique de certaines données, ou vous voulez avoir une référence à un objet sans être "propriétaire" (ce qui pour l'empêcher d'être GC'd), utilisez une référence faible.

187
répondu driekken 2008-11-18 18:27:02

en Java ; ordre du plus fort au plus faible, il y a: fort, doux, faible et fantôme

A référence forte est une référence normale qui protège l'objet visé de la collecte par le GC. c'est à dire Jamais de collecte des ordures.

Un Doux "la référence 151930920" est éligible pour la collecte par le garbage collector, mais ne sera probablement pas recueilli, jusqu'à ce que sa mémoire n'est nécessaire. c'est à dire collecte des ordures avant OutOfMemoryError .

A faible référence est une référence qui ne protège pas un objet référencé de la collecte par le GC. les ordures collecte dans le pas de Forte ou Douce refs.

A référence fantôme est une référence à un objet est référencé de façon fantôme après qu'il a été finalisé, mais avant que sa mémoire attribuée a été récupérée.

Source

analogie: supposons qu'un JVM est un royaume, L'objet est un roi du royaume, et GC est un attaquant du royaume qui tente de tuer le roi(objet).

  • quand le Roi est fort , GC ne peut pas le tuer.
  • quand le Roi est doux , GC l'attaque mais le roi gouverne le royaume avec protection jusqu'à ce que les ressources soient disponibles.
  • quand le Roi est faible , GC l'attaque mais gouverne le royaume sans protection.
  • quand king est Phantom , GC l'a déjà tué mais king est disponible via son âme.
106
répondu Premraj 2017-07-09 08:50:57

Faible Référence http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ref/WeakReference.html

Principe: weak reference concerne le ramassage des ordures. Normalement, l'Objet ayant un ou plusieurs reference ne sera pas admissible à la collecte des ordures.

Le principe ci-dessus n'est pas applicable lorsqu'il s'agit de weak reference . Si un objet n'a qu'faible référence avec d'autres objets, puis son prêt pour la collecte des ordures.

regardons l'exemple ci-dessous: nous avons un Map avec des objets où la clé renvoie à un objet.

import java.util.HashMap;   
public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> aMap = new 
                       HashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        System.out.println("Size of Map" + aMap.size());

    }
}

maintenant, pendant l'exécution du programme nous avons fait emp = null . Le Map tenant la clé n'a aucun sens ici puisqu'il s'agit du null . Dans la situation décrite ci-dessus, l'objet n'est pas une poubelle.

Weaghhashmap

WeakHashMap en est un où les entrées ( key-to-value mappings ) seront supprimées quand il n'est plus possible de les récupérer à partir du Map .

Permettez-moi de montrer l'exemple ci-dessus même avec Weakhmap

import java.util.WeakHashMap;

public class Test {

    public static void main(String args[]) {
        WeakHashMap<Employee, EmployeeVal> aMap = 
                    new WeakHashMap<Employee, EmployeeVal>();

        Employee emp = new Employee("Vinoth");
        EmployeeVal val = new EmployeeVal("Programmer");

        aMap.put(emp, val);

        emp = null;

        System.gc();
        int count = 0;
        while (0 != aMap.size()) {
            ++count;
            System.gc();
        }
        System.out.println("Took " + count
                + " calls to System.gc() to result in weakHashMap size of : "
                + aMap.size());
    }
}

"1519210920 de Sortie": Pris 20 calls to System.gc() entraîner aMap size de : 0.

WeakHashMap n'a qu' des références faibles aux touches, pas des références fortes comme les autres classes Map . Il y a des situations que vous devez prendre soin lorsque la valeur ou la clé est fortement référencée bien que vous ayez utilisé WeakHashMap . Ceci peut être évité en enveloppant l'objet dans un weakref .

import java.lang.ref.WeakReference;
import java.util.HashMap;

public class Test {

    public static void main(String args[]) {
        HashMap<Employee, EmployeeVal> map = 
                      new HashMap<Employee, EmployeeVal>();
        WeakReference<HashMap<Employee, EmployeeVal>> aMap = 
                       new WeakReference<HashMap<Employee, EmployeeVal>>(
                map);

        map = null;

        while (null != aMap.get()) {
            aMap.get().put(new Employee("Vinoth"),
                    new EmployeeVal("Programmer"));
            System.out.println("Size of aMap " + aMap.get().size());
            System.gc();
        }
        System.out.println("Its garbage collected");
    }
}

Doux Références.

Soft Reference est légèrement plus forte que la faiblesse de référence. Soft de référence permet la collecte des ordures, mais supplie le collecteur de les enlever seulement s'il n'y a pas d'autre option.

le collecteur d'ordures ne collecte pas agressivement des objets facilement accessibles comme il le fait avec des objets faiblement accessibles -- au lieu de cela, il ne collecte que des objets facilement accessibles s'il" a besoin " de la mémoire. Les références douces sont une façon de dire au ramasseur d'ordures: "tant que la mémoire n'est pas trop serrée, j'aimerais garder cet objet autour de moi. Mais si la mémoire devient très serré, allez-y, ramassez-le et je m'en occupe."Le ramasseur d'ordures est tenu de nettoyer toutes les références douces avant de pouvoir jeter OutOfMemoryError .

68
répondu Thalaivar 2015-07-21 11:43:18

la seule différence réelle entre une référence molle et une référence faible est que le collecteur d'ordures uses algorithms to decide whether or not to reclaim a softly reachable object, but always reclaims a weakly reachable object.

41
répondu Samir Mangroliya 2012-04-03 15:23:54

SoftReference est conçu pour les caches. Quand on découvre qu'un WeakReference fait référence à un objet inaccessible, il sera immédiatement effacé. SoftReference peut être laissé tel quel. Typiquement, il y a un algorithme relatif à la quantité de mémoire libre et au temps utilisé pour déterminer si elle doit être effacée. L'algorithme Sun actuel est d'effacer la référence si elle n'a pas été utilisée en autant de secondes qu'Il ya des mégaoctets de mémoire libre sur le tas de Java (configurable, serveur HotSpot les contrôles contre le maximum possible de segment défini par les -Xmx ). SoftReference s seront dégagés avant que OutOfMemoryError ne soit lancé, à moins qu'autrement accessible.

21
répondu Tom Hawtin - tackline 2008-11-18 18:32:43

La Seule Différence Réelle

Par le doc , lâche WeakReferences doit être effacé par l'exécution d'un GC.

Par le doc , lâche SoftReferences doit être désactivée avant de OOM est levée.

C'est la seule vraie différence. Tout le reste ne fait pas partie du contrat. (Je suppose que les derniers docs sont contractuels.)

les différences sont utiles. les caches sensibles à la mémoire utilisent des références plus douces, pas des références faibles.


Le seul usage approprié de WeakReference est d'observer la course GC. Vous le faites en créant une nouvelle WeakReference dont l'objet sort immédiatement de la portée, puis essayez d'obtenir null De weak_ref.get() . Quand il est null , vous apprenez qu'entre cette durée, le GC a couru.

As pour incorrect utilisation de weakref, la liste est sans fin:

  • un hack nul pour implémenter la priorité-2 softreference de sorte que vous n'avez pas à en écrire un, pourtant cela ne fonctionne pas comme prévu parce que le cache serait nettoyé sur chaque course GC, même s'il y a de la mémoire de rechange. Voir https://stackoverflow.com/a/3243242/632951 pour phails. (D'ailleurs, quel si vous avez besoin de plus de 2 niveaux de priorité de cache? Il faut une vraie bibliothèque pour ça.)

  • un hack minable pour associer des données avec un objet d'une classe existante, pourtant il crée une fuite de mémoire (OutOfMemoryError) lorsque votre GC décide de prendre une pause après vos références faibles sont créés. En outre, il est au-delà de laid: une meilleure approche est d'utiliser des tuples.

  • un minable hack pour associer des données avec un objet d'une classe existante, où la classe A le nerf de se rendre non-subclassable, et est utilisé dans un code de fonction existant que vous devez appeler. Dans un tel cas, la bonne solution est de modifier la classe et de le rendre subclassable, ou de modifier la fonction et lui faire prendre une interface au lieu d'une classe, ou d'utiliser une autre fonction.

6
répondu Pacerier 2017-09-19 03:27:38

les six types d'objets disponibles en Java -

  1. fort objets accessibles - GC ne sera pas collect ( réclamer la mémoire occupée par ) ce genre d'objets. Il s'agit de accessible via un noeud racine ou un autre objet fortement accessible (c'est-à-dire via des variables locales, variables de classe, variables d'instance, etc.)
  2. Doux ly accessible objets - GC peut tenter pour recueillir ce type d'objets en fonction de la mémoire de contention. Ces sont accessibles à partir de la racine par un ou plusieurs doux objets de référence
  3. faible objets accessibles - GC doit recueillir ce genre d'objets. Ils sont accessibles à partir de la racine via un ou plusieurs objets de référence faibles
  4. objets Ressuscitables objets-GC est déjà en train de recueillir ces objets. Mais ils peuvent revenir à l'un des états - Fort/Doux/Faible par l'exécution de certains finaliseur
  5. Phantom ly reachable object-GC est déjà en cours de collecte de ces objets et a déterminé de ne pas être ressuscitable par un quelconque finalisateur (si elle déclare un finaliser () la méthode elle-même, puis son finalizer aura été lancé) . Ces sont accessibles à partir de la racine par un ou plusieurs fantôme objets de référence
  6. Inaccessible objet - Un objet n'est ni fortement, doucement, faiblement, ni fantôme accessible, et n'est pas resurrectable. Ces objets sont prêts à être remis en état

pour plus de détails: https://www.artima.com/insidejvm/ed2/gc16.html " effondrement

3
répondu V.Vidyasagar 2017-06-19 15:59:25

Faible Référence

Lorsqu'il y a une ou plusieurs références à un objet, il ne s'agit pas de déchets collectés en Java. Mais cette règle dépend du type de référence. Si un objet n'a que de faibles références associées à d'autres objets, il est alors un candidat valable pour la collecte des ordures.

prenons un exemple de scénario pour mieux le comprendre. Que TextView soit un objet (récemment la programmation dans Android et donc en utilisant sa classe pour exemple: -)) et nous aurons les ID générés par le programme utilisés pour son identification. Ces ids sont utilisés dans un autre objet pour référencer les TextViews.

...
Map textViewIdMap = new HashMap();
textViewIdMap.put(textView1, iD1);
textViewIdMap.put(textView2, iD2)
...



la clé est L'objet TextView et la valeur est L'Id. Maintenant, au cours de l'exécution du programme, nous avons supprimé un objet TextView say textView1. Nous n'avons pas besoin de cet objet view, donc nous l'avons rendu nul. Maintenant, qu'arrivera-t-il à la paire clé-valeur(textView1, iD1) stocké dans HashMap. Cette paire n'a plus de sens et n'est pas nécessaire car textview lui-même est null.

donc, programmatique nous devons nous assurer que, lorsqu'un textView est supprimé, son entrée correspondante dans la carte doit être supprimée. Alors seulement, que l'objet devient un candidat pour la collecte des ordures. Sinon, même s'il n'est pas utilisé au moment de l'exécution, cet objet vicié ne sera pas ramassée.





référence molle

la référence molle est légèrement plus forte que la référence faible. La référence douce permet la collecte des ordures, mais supplie le collecteur de les enlever seulement s'il n'y a pas d'autre option. C'est, il est admissible pour la collecte des ordures, mais garbage collector peut l'enlever basé sur la mémoire crunch. S'il est laissé avec peu de mémoire et il est en mesure de récupérer la mémoire, alors il recueillera les références douces.
1
répondu Kumar Shashwat 2017-10-19 15:51:18

Ce article peut être super utile pour comprendre la forte, douce, faible fantôme et de références.


pour vous donner un résumé,

si vous avez seulement références faibles à un objet (sans références fortes), alors L'objet sera récupéré par GC dans le prochain cycle GC.

si vous n'avez que des références douces à un objet (sans références fortes), alors L'objet sera récupéré par GC seulement lorsque JVM s'épuise de mémoire.


ainsi, vous pouvez dire que, des références fortes ont la puissance ultime (ne peut jamais être collecté par GC)

Doux références sont puissant que les références faibles (comme ils peuvent échapper à la GC cycle jusqu'à ce que la JVM est à court de mémoire)

les références faibles sont encore moins puissant que les références douces (car elles ne peuvent pas excaver n'importe quel cycle GC et seront récupérées si l'objet n'a pas d'autre référence forte).


Restaurant Analogie

  • serveur-GC
  • Vous-objet en tas
  • espace de restauration/espace - espace de Segment de mémoire
  • nouveau client-nouvel objet qui veut table au restaurant

maintenant si vous êtes un client fort (analogue à la référence forte), alors même si un nouveau client vient dans le restaurant ou ce qui se passe si jamais, vous ne quitterez jamais votre table (la zone mémoire sur tas). Le garçon n'a pas le droit de vous dire (ou même demander de vous) de quitter le restaurant.

si vous êtes un soft customer (analogue à soft reference), puis si un nouveau client arrive au restaurant, le serveur ne vous demandera pas de quitter la table à moins qu'il n'y ait plus d'autre table vide pour accueillir le nouveau client. (En d'autres termes, le serveur vous demandera de quitter la table seulement si un nouveau client étapes et il n'y a pas d'autre tableau à gauche pour ce nouveau client)

si vous êtes un client faible (analogue à référence faible), alors serveur, à son gré, peut (à tout moment) vous demander de quitter le restaurant: p

1
répondu Lavish Kothari 2018-08-14 18:28:32

il faut être conscient qu'un objet faiblement référencé ne sera collecté que lorsqu'il n'a que de faibles références. Si il a autant comme une référence forte, il n'est pas collectées n'importe comment beaucoup de références faibles.

0
répondu Fai Lau 2016-05-15 04:32:48

WeakReference : les objets qui ne sont que faiblement référencés sont recueillis à chaque cycle GC (mineur ou complet).

SoftReference : lorsque des objets qui ne sont que faiblement référencés sont collectés dépend de:

  1. -XX: SoftRefLRUPolicyMSPerMB = drapeau N (La valeur par défaut est 1000, aka 1 seconde)

  2. Quantité de mémoire libre dans le tas.

    exemple:

    • tas a 10MB d'espace libre (après GC complet);
    • - XX: SoftRefLRUPolicyMSPerMB=1000

    alors l'objet qui est référencé uniquement par SoftReference sera collecté si la dernière fois où il a été accédé est plus grande que 10 Secondes.

0
répondu Artem Petrov 2017-11-05 10:12:52