views:

158

answers:

5

Hello, I would like to ask about Memory Overhead in java, I have a large ArrayList (61,770 items), and trying to calculate the amount of memory taken by each item (counting the object and its ArrayList entry), by profiling the app i get that after all the data is loaded, the heap takes ~ 25Mb. when the ArrayList has only 2 items the heap takes ~1Mb , so roughly:

(24*1024*1024)/61,768 = 407 bytes.

however, when i count the fields of the each object, i get 148 bytes(not including the ArrayList, and assuming int=4,float=4,reference=4), I am curious to know where did all of those extra bytes came from...

i can guess that since the objects I store in the ArrayList are implementing an interface, they store extra values, maybe the VM stores a 4byte function pointer for each implemented method? the interface they implement have 20 functions so thats 80 more bytes, totaling 228 bytes, still not close to the 400 bytes measured.

any help would be appreciated.


wow, thanks for all the great answers.

@Bolo: thanks for the link ,with this class i measure ~350 bytes per object so I can least confirm the source of the large memory usage.

@Yuval A: thank you for that presentation, a valuable source of information.

@Ukko: point noted.

@Jayan: right now NetBeans profiler is giving me errors when i try to dump the heap, will try later again.

+1  A: 

Memory consumed by arraylist is a little vague.

Take a heap dump of the process at appropriate stage - after values are fully assigned. Then use tools like memory analyser (from eclipse).

You fill find shallow and retained heap sizes.

Jayan
+2  A: 

An ArrayList ist mostly bigger than the number of elements. Use getCapacity() to get the current size of the underlying array.

ZeissS
+3  A: 

These results are not surprising. The JVM adds enormous amounts of overhead to each object.

About double the expected size for a single object, due to JVM memory overhead, is not uncommon.

This presentation has a wonderful, in-depth, explanation and overview of various data structure memory usage in Java.

Yuval A
+2  A: 

A big problem with your approach is the interaction with the garbage collector. It basically makes any test like you have proposed totally opaque from the outside.

As a thought experiment if you wanted to do this you should

  1. fire up your JVM and do a couple of global GCs to get all the junk out
  2. Measure the heap size and Java's notion of how much free space it has.
  3. Run your test
  4. GC a couple of times
  5. Redo the measurements from Step #2

After all that and a bit of math you will be closer but still not right. The only real solution is to actually ask the implementation like other people have mentioned. Or figure it out from knowledge of the implementation.

Ukko
A: 

As a side note, since you know exactly how many objects will be in your ArrayList, why not just use an array[]? Will the number of objects in there change?

Dean J
this is just a case example, the exact number of elements to be loaded is not predetermined, my bigger concern is the memory overhead of the object the array points at.