Is Dalvik even more memory hungry than HotSpot in terms of object sizes? Is Dalvik even more memory hungry than HotSpot in terms of object sizes? android android

Is Dalvik even more memory hungry than HotSpot in terms of object sizes?


(Yes, this is an old question, but the results were sort of interesting so I poked at it a bit.)

The Object.clone() method needs to make a full bitwise copy of an object. To do so, it needs to know how big an object is. If you look at dvmCloneObject(), you see that it uses one method for arrays and a different method for objects.

For arrays, it calls dvmArrayObjectSize(), which multiplies the array length by the element width (1, 2, 4, or 8), and then adds the offset of the array data from the start of the object. Every object has an 8-byte header; arrays have a 4-byte width and include an additional 4 bytes of padding to ensure that 64-bit values are aligned properly. So for a 5-element array of short, it would be 16 + 5 * 2.

For ordinary objects, it just uses the objectSize field in the class object. This is set by a rather complicated function called computeFieldOffsets(). That function ensures that all object references come first (so the GC can skip around less when scanning), then follows that with all of the 64-bit fields. To ensure that the 64-bit fields are properly aligned, it may move one of the 32-bit primitive fields up to pad things out. (If there's no appropriate 32-bit field, you just get 4 bytes of padding.)

I should add: all fields are 32-bit, except long and double, which are 64-bit. Object references are 32-bit.

So it's tricky to say exactly how big a non-array object will be, but in general you take the 8-byte object header, sum up the widths of the additional fields, and round up to the next multiple of 8 bytes -- the last because all objects must be 64-bit aligned.

So that's the theory. To see it in practice, I added this to dvmCloneObject():

ALOGD("class=%s size=%d", clazz->descriptor, clazz->objectSize);

and saw logcat output like:

D dalvikvm: class=Ljava/util/Locale; size=24D dalvikvm: class=Ljava/util/Date; size=16

Locale has 4 reference fields, Date has one long field, so these values match expectations.

Ideally, that's exactly how much space would be required. However, the object is allocated with mspace_calloc(), which adds another 4 or (sometimes) 8 bytes of overhead. So the actual space required for the values above would be 32 and 24, which matches your experimental results.


I don't have the answers for you, but I can suggest a couple of places you might look in the source for more information.

You can take a look at the DataObject and ArrayObject structures in dalvik/vm/oo/Object.h. Based on this, it seems like an empty object should only take 8 bytes, while an empty array should take 12 bytes. This doesn't seem to match up with your results, although I'm not sure why.

You might also look at the usages of the objectSize field in the ClassObject struct for more insight. A quick search for usages of that field shows that the dvmAllocObject method in dalvik/vm/alloc/Alloc.cpp seems to be responsible for allocating the memory for new objects.