views:

278

answers:

3

How can one calculate how much memory a Java TreeMap needs to handle each mapping?

I am doing an experiment with 128 threads, each dumping 2^17 longs in its own array. All these 2^24 longs are then mapped to ints (TreeMap<Long,Integer>), each array reference is nulled before moving to the next.

That should amount to 128+64 MB for the keys+values. I am surprised to get OutOfMemoryError during the mapping with 512MB assigned to this VM.

+3  A: 

You seem to assume that a Long, Integer key/value pair in a map occupies only 12 bytes of memory. That is wrong.

Even if you copy from a primitive long array, autoboxing will automatically create Long and Integer object instances as wrappers for the primitive values when you use them as map keys and values. The memory requirements for the object instances is VM implementation specific, but I think that Sun's VM lies in the range 32-48 bytes for these objects, with instances in a 64 bit VM being slightly larger. In addition, the map need additional object instances for each key/value pair to manage the internal data structures.

jarnbjo
Thanks for pointing out the boxing issue which I did not consider in my question. However, 32-48 bytes seems incorrect. If each Long and Integer takes 32 bytes, and the mapping (node) takes 32 bytes (see 280Z28's answer), that would amount to 2^24*(32+32+32)=1536MB.We have bumped up the RAM and can now successfully perform this with 1280MB.
aneas
I was not 100% sure about the memory usage, but you should test it in your runtime environment. With Sun's JDK 1.6.0_10, both Integer and Long instances occupy 20 bytes in the 32-bit VM and 32 bytes in the 64-bit VM. In a TreeMap, a Long/Integer key/value pair occupies 64 bytes in the 32-bit VM and 112 bytes in the 64-bit VM.
jarnbjo
A: 

Apperently from this Tree Map 4 Docs the default size of the tree is 64M. It will report an OutOfMemoryError if you exceeed that. If you don't specify a maximum size it will default to that.

Hope that helps Bob

EDIT: Ignore this. Its all wrong.

scope_creep
I think he is talking about `java.util.TreeMap`, not some third party "Treemap" class.
Stephen C
A: 

Each Long is at least 16 bytes, and each Integer is at least 12 16 bytes, due to the 8-byte object overhead and 8-byte alignment. On a 32-bit machine, each node is at least 24 32 bytes (object header, key, value, two children, and flags for balancing). That means at least 2^24 * (12+24+16) = 832MB.

Edit: It appears objects are 8-byte aligned, so bump the Integer to 16 bytes. Also, a tree node probably has another field for balancing the tree, so count 32 bytes for it. That brings us to a minimum of 1024MB.

280Z28
So a total of 32+16+16=64 bytes for the node+key (Long)+value (Integer), excellent answer!
aneas