2009-09-15 17 views
9

En Java, si creo un Hashtable<K, V> y pongo N elementos en él, ¿cuánta memoria ocupará? Si depende de la implementación, ¿cuál sería una buena "suposición"?¿Cuánta memoria usa una Hashtable?

+0

Probablemente va a estar dominado por el tamaño de la clave y los objetos de valor (a excepción de los mapas pequeños). –

+0

He agregado un cálculo preciso, aunque puede variar con la máquina virtual. Eso no siempre es verdad. Con teclas y valores muy pequeños (por ejemplo, con objetos de envoltura para primitivos), el tamaño de los objetos de entrada puede dominar el tamaño de hashmap/hashtable (internamente son los mismos). Esto también puede suceder si varios valores son referencias a la misma instancia de objeto. Si está utilizando una gran cantidad de objetos primitivos como claves o valores, busque en la biblioteca de Trove. Es más rápido y más eficiente con la memoria para esto. – BobMcGee

Respuesta

12

Editar; Oh, caramba, soy un idiota, di información para HashMap, no HashTable. Sin embargo, después de verificar, las implementaciones son idénticas para propósitos de memoria.

Esto depende de la configuración de la memoria interna de su VM (empaque de elementos, punteros de 32 bit o 64 bit, y alineación/tamaño de palabra) y no está especificado por java.

Se puede encontrar información básica sobre la estimación del uso de la memoria here.

Se puede estimar que de este modo:

  • en 32 bits máquinas virtuales, un puntero es de 4 bytes, en máquinas virtuales de 64 bits, que es de 8 bytes.
  • La sobrecarga del objeto es 8 bytes de memoria (para un objeto vacío, que no contiene nada)
  • Los objetos están acolchados a un tamaño que es un múltiplo de 8 bytes (ugh).
  • Hay una sobrecarga pequeña y constante para cada hashmap: un flotador, 3 ints, más sobrecarga del objeto.
  • Hay una variedad de ranuras, algunas de las cuales tendrán entradas, algunas de las cuales estarán reservadas para las nuevas. La proporción de ranuras llenas a ranuras totales NO ES MÁS QUE el factor de carga especificado en el constructor.
  • La matriz de ranuras requiere una sobrecarga de objetos, más uno por tamaño, más un puntero por cada ranura, para indicar el objeto almacenado.
  • El número de ranuras generalmente es de 1.3 a 2 veces más que el número de asignaciones almacenadas, con un factor de carga predeterminado de 0.75, pero puede ser menor que esto, dependiendo de las colisiones hash.
  • Cada asignación almacenada requiere un objeto de entrada. Esto requiere una sobrecarga de objetos, 3 punteros, más la clave almacenada y los objetos de valor, más un número entero.

lo tanto, poner juntos (para 32/64 bit Sun HotSpot JVM): HashMap necesita 24 bytes (en sí misma, campos primtive) + 12 bytes (ranura matriz constante) + 4 u 8 bytes por ranura + 24/40 bytes por entrada + tamaño del objeto + valor del tamaño de clave de objeto + acolchado cada objeto a múltiplo de 8 bytes

OR, más o menos (en la mayoría de los ajustes por defecto, no garantiza que sea preciso):

  • En JVM de 32 bits: 36 bytes + 32 bytes/mapeo + Teclas & valora
  • En JVM de 64 bits: 36 bytes + 56 bytes + llaves/mapeo & valora

Nota: Esta necesita más comprobación, puede necesitar 12 bytes para sobrecarga de objetos en VM de 64 bits. No estoy seguro acerca de los nulos: los punteros para nulos pueden comprimirse de alguna manera.

4

Es difícil de estimar. Me gustaría leer este primero: http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html

Sólo tiene que utilizar las herramientas sunjdk de averiguar el tamaño de K, V y

jmap -histo [pid]

num #instances #bytes nombre de la clase

1: 126.170 19.671.768 MyKClass

2: 126170 14392544 MyVClass

3: 1 200000 MyHashtable

También es posible que desee utilizar HashMap en lugar de Hashtable si no necesita sincronización.

Cuestiones relacionadas