Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory required for 'short' fields in Dalvik?

Java virtual machines may use int-sized width for short fields as well (this depends on their internal implementation). Only the arrays (short[]) are exception, where it is always guaranteed that they take less space than an int[] internally as well). What about Dalvik?

E.g. I have a class which contains 50 fields of type short. Sometimes in my application, 10000 of these classes exist. This means that the short fields should use 1MB of memory, but if Dalvik uses 4 bytes for short values internally, then this will be 2MB memory usage.

How much memory should I expect Dalvik to use? (This refers to its internal memory use, and I'm aware of the fact that it might not be reflected by the system memory usage, e.g. because Dalvik already reserved a higher amount of memory from the system.)

like image 936
Thomas Calc Avatar asked Oct 25 '12 14:10

Thomas Calc


2 Answers

In dalvik, double and long fields are 8 bytes, everything else (including short) is 4 bytes.

On the other hand, short arrays take 2 bytes per element (in addition to up-front space for the array+object bookkeeping).

Arrays

The new-array opcode calls dvmAllocArrayByClass (line 71) to allocate space. This then calls dvmAllocPrimitiveArray (line 113). In the switch in dvmAllocPrimitiveArray, the 'S' case is used for a short array. You can see it calls allocArray (line 38) with width=2.

Within allocArray, it does the following computation to calculate the size size of the array:

size_t elementShift = sizeof(size_t) * CHAR_BIT - 1 - CLZ(elemWidth);
size_t elementSize = length << elementShift;
size_t headerSize = OFFSETOF_MEMBER(ArrayObject, contents);
size_t totalSize = elementSize + headerSize;

For a short, on a 32 bit system, this calculation would be:

size_t elementShift = (4 * 8) - 1 - 30; //== 1;
size_t elementSize = length << 1; //i.e. length * 2
size_t headerSize = <some constant value>;
size_t totalSize = length*2 + <some constant value>;

Short arrays take 2 bytes per element.

Fields

The new-instance opcode calls dvmAllocObject (line 181) to allocate space for the new object. The size that is allocated is based on the objectSize field of ClassObject. objectSize is set in computeFieldOffsets (line 3543). If you find every instance of where fieldOffset is incremented in this function, you will notice it is always incremented in steps of 4 bytes.

Short fields take 4 bytes.

like image 74
JesusFreke Avatar answered Sep 29 '22 01:09

JesusFreke


(Would be a comment, but it's too long for that.)

It's fairly routine for 4-byte fields to be used for "short" local vars, since the JVM is conceptually a machine with 4-byte registers, and with all the other garbage in a stack frame it doesn't make much difference.

For instance fields it's likely to depend on the tradeoff of saving storage vs having to spend cycles on widening and alignment -- widening often costs a minor cycle, and even on architectures that are supposedly "agnostic" with regard to boundary alignment there's usually a penalty for off-boundary access, so "packing" fields without first rearranging them to maintain word/doubleword boundaries can cost performance.

So if the JVM chooses to "pack" the fields rearranging is generally required. Naive JVMs will avoid rearranging since this makes several aspects of the JVM simpler, but (as one example) on AS/400 we found that aggressively reordering and packing instance fields gained on the order of 30% performance improvement for storage-hungry apps.

I've never looked at the innards of Dalvik. Standard Sun-derived JVMs have historically (not looked at anything recent) been dependent on the layout/order of things in the .class file, and thus not "naturally" amenable to reordering. But Dalvik re-constitutes the .class file and so is in a better position to do instance field reordering.

Note that to test the hypothesis that Dalvik packs short fields you'd have to create a class with several dozen instance fields back-to-back, and then determine what the resulting object size was. Also (assuming packing is seen in the first case), create a class with short and int (or maybe long) fields interleaved, to see if Dalvik reorders them to achieve packing.

like image 45
Hot Licks Avatar answered Sep 29 '22 03:09

Hot Licks