views:

980

answers:

2

In Java, if I create a Hashtable<K, V> and put N elements in it, how much memory will it occupy? If it's implementation dependent, what would be a good "guess"?

+4  A: 

It is hard to estimate. I would read this first: http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html

Just use the sunjdk tools to figure out the size of K, V and

jmap -histo [pid]

num #instances #bytes class name

1: 126170 19671768 MyKClass

2: 126170 14392544 MyVClass

3: 1 200000 MyHashtable

Also you may want to use HashMap instead of Hashtable if you do not need synchronization.

Boune
+5  A: 

Edit; Oh geez, I'm an idiot, I gave info for HashMap, not HashTable. However, after checking, the implementations are identical for memory purposes.

This is dependent on your VM's internal memory setup (packing of items, 32 bit or 64 bit pointers, and word alignment/size) and is not specified by java.

Basic info on estimating memory use can be found here.

You can estimate it like so:

  • On 32-bit VMs, a pointer is 4 bytes, on 64-bit VMs, it is 8 bytes.
  • Object overhead is 8 bytes of memory (for an empty object, containing nothing)
  • Objects are padded to a size that is a multiple of 8 bytes (ugh).
  • There is a small, constant overhead for each hashmap: one float, 3 ints, plus object overhead.
  • There is an array of slots, some of which will have entries, some of which will be reserved for new ones. The ratio of filled slots to total slots is NO MORE THAN the specified load factor in the constructor.
  • The slot array requires one object overhead, plus one int for size, plus one pointer for every slot, to indicate the object stored.
  • The number of slots is generally 1.3 to 2 times more than the number of stored mappings, at default load factor of 0.75, but may be less than this, depending on hash collisions.
  • Every stored mapping requires an entry object. This requires one object overhead, 3 pointers, plus the stored key and value objects, plus an integer.

So, putting it together (for 32/64 bit Sun HotSpot JVM): HashMap needs 24 bytes (itself, primtive fields) + 12 bytes (slot array constant) + 4 or 8 bytes per slot + 24/40 bytes per entry + key object size + value object size + padding each object to multiple of 8 bytes

OR, roughly (at most default settings, not guaranteed to be precise):

  • On 32-bit JVM: 36 bytes + 32 bytes/mapping + keys & values
  • On 64-bit JVM: 36 bytes + 56 bytes/mapping + keys & values

Note: this needs more checking, it might need 12 bytes for object overhead on 64-bit VM. I'm not sure about nulls -- pointers for nulls may be compressed somehow.

BobMcGee