hi, regarding the memory consumption of a tuple containing 1 object reference, i believe the following to be (more) accurate:
1. the tuple Avail object: -1 object header @ 8 bytes (klass pointer + monitor + gc bits). - 3 slots in the AvailObject itself (descriptor ref, objectSlots ref, intSlots ref) @ 4 bytes * total of 24 bytes (padded) but… we also need to take the descriptor object, integer array and object array into account: 2. the descriptor object: … are shared and globally allocated once - so not taken into account. 3. the integer array object containing 1 int (the hash) - 1 object header @ 8 bytes - 1 size slot @ 4 bytes - 1 int @ 4 bytes * total of 16 bytes * 4. the object array object containing 1 object reference - 1 object header @ 8 bytes - 1 size slot @ 4 bytes - 1 object reference @ 4 bytes * total of 16 bytes * a total of 56 bytes on a 32 bits jvm. on a 64 bit jvm, that figure is going to be obviously worse: uncompressed, every object header goes from 8 to 16 bytes and every object reference goes from 4 to 8 bytes: 1. tuple object (64 bit, uncompressed): 40 bytes 2. integer array (64 bit, uncompressed): 24 bytes 3. object array (64 bit, uncompressed): 32 bytes (padded). a total of 96 bytes o a 64 bit jvm - uncompressed. compressed, every object header goes from 8 to 12 bytes and every object reference will stay 4 bytes (if the heap stay below 4 gig). 1. tuple object (64 bit, compressed): 24 bytes 2. integer array (64 bit, compressed): 24 bytes (padded). 3. object array (64 bit, compressed): 24 bytes (padded). a total of 72 bytes on a 64 bit jvm - compressed. that’s 3 times as big as a regular java object array containing one object reference. i’m sure the llvm memory representation will be much better. cheers, - robbert > Like all AvailObjects, a tuple has the usual Java header and two slots, one > for the array of AvailObjects and one for the array of ints. An ordinary > tuple (not one containing, say, a character or a nybble) has one object slot > and one integer slot, so both arrays are necessary. When there are zero > object slots or integer slots in an AvailObject, the single shared empty > array of objects or the single shared empty array of ints is used instead of > creating one especially for that AvailObject. However, since we need one > slot of each for the one-element ordinary tuple (whose descriptor is an > ObjectTupleDescriptor), we have: > > 3 object headers (AvailObject, AvailObject [], int []) @ 8 bytes each, > 3 slots in the AvailObject itself (descriptor, objectSlots, intSlots) @ > 8 bytes each > 1 slot in the int [] @ 4 bytes (to cache the tuple's hash value) > 1 slot in the AvailObject [] @ 8 bytes (the tuple element) > > So a one-element tuple takes 60 bytes. On the other hand, the zero element > tuple is shared and takes no additional space per use (the slot holding it > would be accounted with whatever structure owns the slot). > > Compressed pointers would shave it to 44 bytes. The custom representation > we'll be using with LLVM will look like: > > ...before the object... > [tuple element #1] @ 8 bytes > [middle-header] @ 8 bytes > [int slot #1 for hash] @ 4 bytes > ...after the object... > > = 20 bytes.
