2009-09-15 4 views
9

En Java, si je crée un Hashtable<K, V> et y place N éléments, combien de mémoire occupera-t-il? Si cela dépend de la mise en œuvre, qu'est-ce qui serait une bonne «supposition»?Quelle quantité de mémoire utilise une Hashtable?

+0

Il sera probablement dominé par la taille de vos objets clé et valeur (sauf pour les petites cartes). –

+0

J'ai ajouté un calcul précis, bien qu'il puisse varier avec la VM. Ce n'est pas toujours vrai. Avec de très petites clés et valeurs (par exemple, avec des objets wrapper pour les primitives), la taille des objets Entry peut dominer la taille de hashmap/hashtable (en interne, ils sont identiques). Cela peut également se produire si plusieurs valeurs sont des références à la même instance d'objet. Si vous utilisez beaucoup d'objets primitifs en tant que clés ou valeurs, regardez dans la bibliothèque Trove. C'est plus rapide et plus efficace pour cela. – BobMcGee

Répondre

12

Editer; Oh bon sang, je suis un idiot, j'ai donné des infos pour HashMap, pas HashTable. Cependant, après vérification, les implémentations sont identiques à des fins de mémoire.

Ceci dépend de la configuration de la mémoire interne de votre machine virtuelle (conditionnement des éléments, pointeurs 32 bits ou 64 bits et alignement/taille des mots) et n'est pas spécifiée par java.

Les informations de base sur l'estimation de l'utilisation de la mémoire peuvent être trouvées here.

Vous pouvez estimer comme si:

  • Sur les machines virtuelles 32 bits, un pointeur est 4 octets, sur les machines virtuelles 64 bits, il est de 8 octets.
  • La surcharge de l'objet est de 8 octets de mémoire (pour un objet vide ne contenant rien)
  • Les objets sont remplis à une taille multiple de 8 octets (ugh).
  • Il y a une petite surcharge constante pour chaque hashmap: un flottant, 3 ints, plus le surdébit de l'objet.
  • Il y a un tableau de slots, dont certains auront des entrées, dont certaines seront réservées aux nouvelles. Le taux de slots remplis par rapport au nombre total de slots n'est AUCUN PLUS QUE le facteur de charge spécifié dans le constructeur.
  • Le tableau d'emplacements requiert un préfixe d'objet, plus un int pour la taille, plus un pointeur pour chaque emplacement, pour indiquer l'objet stocké.
  • Le nombre d'emplacements est généralement 1,3 à 2 fois supérieur au nombre de mappages stockés, avec un facteur de charge par défaut de 0,75, mais peut être inférieur à ce nombre, en fonction des collisions de hachage.
  • Chaque mappage stocké nécessite un objet d'entrée. Cela nécessite un overhead d'objet, 3 pointeurs, plus les objets key et value stockés, plus un entier.

Ainsi, mettre ensemble (pour 32/64 bit Sun JVM HotSpot): HashMap a besoin de 24 octets (elle-même, les champs primtive) + 12 octets (constante de réseau de fente) + 4 ou 8 octets par intervalle + 24/40 octets par entrée + taille de l'objet clé + valeur taille de l'objet + padding chaque objet à un multiple de 8 octets

OU, à peu près (dans la plupart des paramètres par défaut, non garanti pour être précis):

  • Sur JVM 32 bits: 36 octets + 32 octets/mapping + touches & valeurs
  • Sur JVM 64 bits: 36 octets + 56 octets/mapping + touches & valeurs

Note: cette a besoin de plus de vérification, il peut avoir besoin de 12 octets pour la surcharge de l'objet sur une machine virtuelle 64 bits. Je ne suis pas sûr au sujet des nulls - les pointeurs pour les nulls peuvent être compressés d'une manière ou d'une autre.

4

Il est difficile à estimer. Je lirais cette première: http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html

Il suffit d'utiliser les outils de sunjdk pour déterminer la taille de K, V et

jmap -histo [pid]

num #instances #bytes nom de classe

1: 126170 19671768 MyKClass

2: 126170 14392544 MyVClass

3: 1 200000 MyHashtable

Vous pouvez également utiliser HashMap au lieu de Hashtable si vous n'avez pas besoin de synchronisation.

Questions connexes