You might want to read this SO question. The object overhead will vary between different CPU architectures, VM implementations and between different Java versions (e.g. OOPS, there are also suggestions of fixnums etc.).
But let's see for ourselves for OpenJDK 7, the HashMap
class:
Overhead is 48 bytes for HashMap
Housekeeping info. Presumably 8 bytes.
There are three fields in the implementation that hold the views made by keySet()
, values()
and entrySet()
methods. Three pointers, that's 12 bytes on a 32-bit machine.
// from AbstractMap
transient volatile Set<K> keySet = null;
transient volatile Collection<V> values = null;
// from HashMap
private transient Set<Map.Entry<K,V>> entrySet = null
There are three int
fields: size
, threshold
and modCount
. 12 bytes.
There is one float
field: loadFactor
. 4 bytes.
The table pointer itself (Entry[] table
). 4 bytes.
(the static final
fields don't count, they are compile-time constants)
All that gives us 40 bytes flat cost of a HashMap
instance. It's not 48 bytes and I don't know why. Maybe I missed something, maybe your text referred to other version. These things sometimes change a little. There may have been an extra field in the past. Maybe it's padded from 40 to 48 bytes (but it shouldn't).
16 + (entries * 4 bytes) for array
The Entry[] table
table is instantiated when the HashMap
is constructed, we need to count it, too.
An instantiated array takes 8 bytes of housekeeping data, 4 bytes
for the length
property. That's 12 bytes, not 16. Again, no idea where that comes from.
Every entry is a pointer to an Entry
object, so that's 4 bytes per entry. That was easy.
Additional 32 bytes per key ↔ value entry
Again, 8 bytes of housekeeping.
Now, the fields:
final K key; // a reference, 4 bytes
V value; // a reference, 4 bytes
Entry<K,V> next; // a reference, 4 bytes
final int hash; // an integer primitive, 4 bytes
16 bytes.
That's a final count of 24 bytes per entry. Again, that's not 36.
I have no idea where the numbers you got there come from. Could that be an IBM vm? Could that be a 64-bit OS? Maybe the the housekeeping info is 16 bytes nowadays (will Java 8 change anything?).
Anyway, I tried to compute the memory consumption to my best knowledge.