[Effective Java] Supprimer les références d'objet obsolètes

La propre interprétation efficace de Java. J'ai essayé d'interpréter le point 7 de la 3e édition en écrivant mon propre code.

Aperçu

Connaissances préalables

Collecte des ordures

Java a une fonctionnalité selon laquelle le garbage collector supprime automatiquement les objets qui ne sont plus référencés.

Par exemple, dans le code suivant, les objets «« hoge0 »«, «hoge1» «,« hoge2 »» de «String» sont créés dans la boucle «for», mais la variable de référence «hoge» fait glisser la cible de référence dans l'ordre. Les objets " hoge0 ", " hoge1 " sont supprimés par le ramasse-miettes.

String hoge = null;

for (int i = 0; i < 3 ; i++){
    hoge = "hoge" + i;
}

del-object-Page-1.jpg

En revanche, l'objet dont la référence demeure n'est pas effacé et reste indéfiniment en mémoire. Dans le code ci-dessous, les objets sont stockés dans un tableau, mais avec hoge [0], hoge [1], hoge [2], " hoge0 ", " hoge1 ", " hoge2 " Comme chacun peut être référencé, il ne sera pas supprimé dans le ramasse-miettes et l'objet restera en mémoire.

String[] hoges = new String[3];

for (int i = 0; i < 3; i++) {
    hoges[i] = "hoge" + i;
}

del-object-Copy of Page-1.jpg

Anti-modèles et solutions

Pile maison

Une pile est une structure de données Last In First Out. Il peut être facilement implémenté en utilisant l 'interface Deque, mais ici j'ose l'implémenter. Montez à la main.

** Classe de pile maison **

public class Stack {

    /**
     *Tableau pour pile
     */
    private String[] hoges;

    /**
     *Nombre actuel d'éléments de pile
     */
    private int currentElementCount = 0;

    /**
     *constructeur
     *Définir la taille de la pile
     */
    public Stack() {
        this.hoges = new String[3];
    }

    /**
     *Pousser pour empiler
     *
     * @param str string à pousser
     */
    public void push(String str) {
        hoges[currentElementCount] = str;
        currentElementCount = currentElementCount + 1;
    }

    /**
     *Pop de la pile
     *
     * @return Chaîne sautée
     */
    public String pop() {
        if (currentElementCount == 0) {
            throw new EmptyStackException();
        }
        currentElementCount = currentElementCount - 1;
        return hoges[currentElementCount];
    }
}

Si vous faites cette classe, Push, vous pouvez certainement obtenir l'élément, et si vous faites Pop, vous pouvez obtenir le dernier élément, mais il y a un problème. Comme il ne déplace le numéro de référence que lors de la saisie, la référence de l'objet elle-même reste.

del-object-Page-3 (1).jpg

La logique est correcte et l'élément poppé ne sera plus jamais utilisé, mais le garbage collector ne peut pas dire s'il va être supprimé car la référence reste. Dans cet exemple, la taille maximale de la pile est de 3, donc au plus 3 objets restent en mémoire, mais des piles volumineuses peuvent provoquer de graves problèmes de mémoire. Ce problème peut être résolu en plaçant intentionnellement Null dans l'élément correspondant du tableau lors de l'ouverture et de la suppression de la référence à l'objet d'origine.

del-object-Page-4.jpg

Cependant, si vous voulez vraiment utiliser la pile, utilisez l 'interface Deque. Faisons le.

Déclaration de variable non utilisée

Parfois, il est trop tôt pour déclarer une variable, laissant l'objet en mémoire en vain. Dans le code ci-dessous, il y a un problème avec la déclaration prefix.

/**
 *Renvoie une chaîne de nombres jusqu'au nombre de boucles spécifié
 *Ajouter un préfixe si la longueur dépasse le seuil spécifié
 *
 * @param limitLength Seuil de chaîne
 * @param loopCount Nombre de boucles
 * @Une chaîne créée par la boucle de retour
 */
public String hoge(int limitLength, int loopCount) {

    String prefix = "Over" + limitLength + ": ";

    StringBuilder str = new StringBuilder();
    for (int i = 0; i < loopCount; i++) {
        str.append(i);
    }

    if (str.length() > limitLength) {
        return prefix + str;
    } else {
        return str.toString();
    }
}

Il y a deux problèmes.

--L'objet reste en mémoire jusqu'à ce qu'il soit réellement utilisé dans le bloc ʻif. --Parce que vous le déclarez en dehors du bloc ʻif, l'objet reste en mémoire même si vous entrez ʻelse`.

Le problème ci-dessus peut être résolu en le déclarant juste avant l'endroit où il est réellement utilisé comme suit.

    if (str.length() > limitLength) {
        String prefix = "Over" + limitLength + ": ";
        return prefix + str;
    } else {
        return str.toString();
    }

Dans le cas d'une méthode longue, elle n'est souvent pas remarquée de manière inattendue, alors soyez prudent.

Recommended Posts

[Effective Java] Supprimer les références d'objet obsolètes
[Lire Java efficace] Chapitre 2 Item 6 "Supprimer les références d'objets obsolètes"
Java (supprimer)
Efficace Java Chapitre 2
Effective Java Chapitre 6 34-35
[Java] Classe d'objets
Effective Java Chapitre 4 15-22
Java efficace Chapitre 3
Sensation de la taille de l'objet Java
Effective Java 3rd Edition Chapitre 2 Création et disparition d'objets
Modèle de générateur (Java effectif)
Sérialisation d'objets Java pourquoi et quand
Muscle Java Orienté Objet Jour 1
De Java inefficace à Java efficace