Est Java HashMap.clear() et remove() de la mémoire efficace?

Envisager la follwing HashMap.clear() code:

 /**
 * Removes all of the mappings from this map.
 * The map will be empty after this call returns.
 */
public void clear() {
    modCount++;
    Entry[] tab = table;
    for (int i = 0; i < tab.length; i++)
        tab[i] = null;
    size = 0;
}

Il semble que le tableau interne (table)Entry les objets ne sont jamais rétrécis. Donc, quand j'ajoute 10000 éléments à une carte, et après cet appel map.clear(), il gardera 10000 nulls dans son réseau interne. Donc, ma question Est, comment JVM gère ce tableau de rien, et donc, est HashMap mémoire efficace?

37
demandé sur Joe Doyle 2010-05-11 18:29:56

4 réponses

L'idée est que clear() n'est appelé que lorsque vous voulez réutiliser le HashMap. Réutiliser un objet ne devrait être fait que pour la même raison qu'il a été utilisé auparavant, donc les chances sont que vous aurez à peu près le même nombre d'entrées. Pour éviter le rétrécissement inutile et le redimensionnement de la Map la capacité est le même lorsque clear() est appelée.

Si tout ce que vous voulez faire est de supprimer les données dans le Map, alors vous ne devez pas (et en fait ne devrait pas appeler)clear() sur elle, mais simplement effacer toutes les références à l' Map elle - même, auquel cas elle finira par être ramassée.

59
répondu Joachim Sauer 2010-05-11 14:33:28

en Regardant le code source, il ne ressemble à HashMap ne rétrécit jamais. resize la méthode est appelée pour doubler la taille quand c'est nécessaire, mais n'a rien ala ArrayList.trimToSize().

si vous utilisez un HashMap de telle sorte qu'il pousse et rétrécit dramatiquement souvent, vous pouvez créer un nouveau HashMap au lieu d'appeler clear().

10
répondu polygenelubricants 2010-05-11 14:41:40

vous avez raison, mais considérant que l'augmentation du tableau est une opération beaucoup plus chère, il n'est pas déraisonnable pour le HashMap de penser "une fois que l'Utilisateur a augmenté le tableau, les chances sont qu'il aura besoin du tableau de cette taille à nouveau plus tard" et il suffit de quitter le tableau au lieu de le diminuer et de risquer de devoir l'étendre de façon coûteuse plus tard. C'est un heuristique je suppose - vous pourriez préconiser l'inverse aussi.

4
répondu Konerak 2010-05-11 14:34:11

une Autre chose à considérer est que chaque élément table est simplement une référence. Définir ces entrées à null supprimera les références des éléments de votre Map, qui sera alors libre pour la collecte des ordures. Ce n'est donc pas comme si vous ne libériez aucun souvenir.

Toutefois, si vous avez besoin de même que la mémoire utilisée par le Map elle-même, alors vous devriez la libérer selon la suggestion de Joachim Sauer.

4
répondu danben 2010-05-11 14:38:50