887 votes

Quelle est la différence entre un soft de référence et une référence faible en Java?

Le titre assez bien sommes.

1001voto

Michael Myers Points 82361

À partir de la Compréhension des Références Faibles, par Ethan Nicolas:

Références faibles

Une référence faible, c'est tout simplement un de référence qui n'est pas assez fort pour forcer un objet à rester en mémoire. La faiblesse des références vous permettent de tirer parti de le garbage collector de la capacité de déterminer l'accessibilité pour vous, alors vous n'avez pas à le faire vous-même. 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() d'obtenir le véritable 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 les références à le widget) weakWidget.get() tout d'un coup commence de retour null.

...

Doux références

Un soft de référence 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 (le plus fort ses 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écessairesà 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 l'offre est abondante. Cela fait d'eux une excellente base pour une cache, tels comme le cache des images décrites ci-dessus, puisque vous pouvez laisser la poubelle collecteur de vous soucier de combien accessible les objets sont (fortement accessible objet ne jamais être supprimé à partir du cache) et à quel point il a besoin le mémoire qu'ils consomment.

Et Peter Kessler ajouté dans un commentaire:

La JRE de Sun ne traiter SoftReferences différemment de WeakReferences. Nous essayons de tenir à l'objet référencé par un SoftReference si il n'y a pas de pression sur la mémoire disponible. Un détail: la politique du "client" et "serveur" JRE sont différentes: le client JRE essaie de garder votre faible empreinte en préférant clair SoftReferences plutôt que de développer le tas, tandis que le serveur JRE essaie de garder vos performances de haut en préférant développer le tas (si possible) plutôt que de les effacer SoftReferences. Une taille unique ne convient pas à tous.

225voto

driekken Points 2548

Références faibles sont collectées avec impatience. Si GC trouve qu'un objet est faiblement accessible (accessible uniquement par le biais de références faibles), il va dégager la la faiblesse des 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é) "informations associées" quelque part, comme la mise 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 auquel il est associé avec GC-ed. Lorsque la référence faible est effacée, il obtient en file d'attente dans un référence de la file d'attente de votre code sondages, quelque part, et il ignore l' les objets associés. Qui est, vous gardez extra d'informations sur un objet, mais que l'information n'est pas nécessaire une fois que l'objet qu'il désigne s'en va. En fait, dans certaines situations, vous pouvez même sous-classe WeakReference et de garder les associés de l'information supplémentaire à propos de l'objet dans les domaines de la WeakReference sous-classe. Un autre exemple d'utilisation de WeakReference est en conjonction avec des Cartes pour garder canonique instances.

SoftReferences d'autre part, sont bonnes pour la mise en cache externe, recreatable ressources comme la GC généralement des retards de compensation. Il est garanti bien que tous les SoftReferences aurez effacé avant de OutOfMemoryError est levée, de sorte qu'ils théoriquement, ne peut pas provoquer une OOME[*].

Cas d'utilisation typique exemple de garder un analysée forme d'un contenu à partir d'un fichier. Vous auriez du mettre en place un système où vous chargez un fichier, l'analyser, et de garder un SoftReference à la racine de l'objet de l'analyse de la représentation. La prochaine fois vous avez besoin du fichier, vous allez essayer de le récupérer par la SoftReference. Si vous pouvez le récupérer, vous vous épargner une autre charge/parse, et si le GC effacé en attendant, vous le recharger. De cette façon, vous utiliser gratuit mémoire pour l'optimisation des performances, mais ne prenez pas le risque d'une OOME.

Maintenant, pour le [*]. En gardant un SoftReference peut pas causer un OOME en lui-même. Si d'autre part, par erreur, vous utilisez SoftReference pour une tâche d'une WeakReference est destiné à être utilisé (à savoir, vous conservez les informations associées à un Objet en quelque sorte fortement référencé, et le jeter lorsque l'objet de Référence obtient désactivée), vous pouvez exécuter dans OOME que votre code qui interroge le ReferenceQueue et supprime les objets associés peut arriver à ne pas s'exécuter dans un temps opportun de la mode.

Ainsi, la décision dépend de l'utilisation - si vous êtes à la mise en cache de l'information qui est cher à construire, mais néanmoins reconstructible à partir d'autres données, utiliser des références - si vous êtes en gardant une référence à un exemple canonique de certaines données, ou vous voulez avoir une référence à un objet sans être "propriétaire" (ce qui la prévention de la GC avait), l'utilisation d'une référence faible.

82voto

Vinothbabu Points 6643

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

weak reference est liée à la collecte des déchets. Normalement, l'objet d'une ou de plusieurs reference ne seront pas admissibles pour la collecte des ordures. Thea règle ci-dessus n'est pas applicable lorsqu'il est weak reference. Un objet a que de faibles référence à d'autres objets, puis de son prêt pour la collecte des ordures.

Reprenons maintenant l'exemple ci-dessous. Nous avons une Carte avec des Objets où la Clé est une Classe de l'objet de Référence.

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, lors de l'exécution du programme, nous avons fait emp = null. La Carte de la tenue de la clé n'a pas de sens ici comme il est null. Dans le ci-dessus situaton, l'objet n'est pas de ces ordures.

WeakHashMap

WeakHashMap est celui où les entrées (key-to-value mappings) sera supprimé quand il n'est plus possible de les récupérer à partir de la carte.

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

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());
    }
}

Prit 20 calls to System.gc() de résultat en aMap size de la : 0.

WeakHashMap a seulement la faiblesse des références aux touches, pas de solides références comme les autres Map les classes. Il y a des situations qui vous devez prendre soin lors de la valeur ou de la clé est fortement référencé, si vous avez utilisé WeakHashMap. Cela peut éviter par emballage de l'objet dans un WeakReference.

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 pour la collecte des ordures, mais soulève le garbage collector pour effacer uniquement si il n'y a pas d'autre option.

Le garbage collector n'est pas agressive recueillir doucement accessible objets de la manière qu'il le fait avec faiblement accessible -- au lieu de cela, il ne recueille doucement accessible objets si c'est vraiment "besoin" de la mémoire. Doux références sont une façon de dire que le garbage collector, "aussi longtemps Que la mémoire n'est pas trop serrée, j'aimerais garder cet objet autour de la. Mais si la mémoire devient vraiment serré, aller de l'avant et de les collecter et je vais y répondre." Le garbage collector est nécessaire pour effacer toutes les références avant de jeter OutOfMemoryError.

56voto

Samir Mangroliya Points 21263

La seule vraie différence entre un soft de référence et une référence faible, c'est que le garbage collector uses algorithms to decide whether or not to reclaim a softly reachable object, but always reclaims a weakly reachable object.

28voto

SoftReference est conçu pour les caches. Lorsqu'il est constaté qu'un WeakReference références d'un objet inaccessible, elle sera effacé immédiatement. SoftReference peut être laissé tel qu'il est. Généralement, il existe un algorithme relatives à la quantité de mémoire disponible et l'heure de la dernière utilisation afin de déterminer si elle doit être effacée. Le courant de Soleil algorithme est d'effacer la référence si elle n'a pas été utilisé comme le nombre de secondes qu'il y a des méga-octets de mémoire libre sur le tas Java (configurable, serveur HotSpot les contrôles contre le maximum possible de segment défini par -Xmx). SoftReferences sera effacé avant d' OutOfMemoryError est levée, sauf si accessible.

Prograide.com

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.

Powered by:

X