9

Here are the two samples I would like to base my question on (assuming you have JOL here):

Layouter layout32Bits =  new HotSpotLayouter(new X86_32_DataModel());
Layouter layout64BitsComp = new HotSpotLayouter(new X86_64_COOPS_DataModel());

And an example using this:

int [] ints = new int[10];  

System.out.println(ClassLayout.parseInstance(ints, layout32Bits).toPrintable());
System.out.println(ClassLayout.parseInstance(ints, layout64BitsComp).toPrintable());

And here are the two outputs:

  [I object internals:
  OFFSET  SIZE   TYPE DESCRIPTION             VALUE
  0     4        (object header)     09 00 00 00 (00001001 00000000 00000000 00000000) (9)
  4     4        (object header)     00 00 00 00 (00000000 00000000 00000000 00000000) (0)
  8     4        (object header)     10 1b 0c 1a (00010000 00011011 00001100 00011010) (437000976)
 12    40    int [I.<elements>            N/A
 52    12        (loss due to the next object alignment)
 Instance size: 64 bytes
 Space losses: 0 bytes internal + 12 bytes external = 12 bytes total

  [I object internals:
  OFFSET  SIZE   TYPE DESCRIPTION             VALUE
  0     4        (object header)     09 00 00 00 (00001001 00000000 00000000 00000000) (9)
  4     4        (object header)     00 00 00 00 (00000000 00000000 00000000 00000000) (0)
  8     4        (object header)     10 1b 0c 1a (00010000 00011011 00001100 00011010) (437000976)
 12     4        (object header)     01 00 00 00 (00000001 00000000 00000000 00000000) (1)
 16    40    int [I.<elements>            N/A
 56     8        (loss due to the next object alignment)
 Instance size: 64 bytes
 Space losses: 0 bytes internal + 8 bytes external = 8 bytes total

I mainly understand the output, the thing I don't is what are these:

12 bytes external and 8 bytes external

In general, Objects are 8 bytes aligned, so why the need to add more padding than needed?

I know about a few things that are somehow weird, the first one has to do with the API that JOL is using and the second has to do with internal data, that needs to be hidden.

I also know about this, but it seems un-related, as it means internal padding.

Can someone shed some light on this?

Eugene
  • 117,005
  • 15
  • 201
  • 306
  • [Aren't alignments always a power of 2?](https://electronics.stackexchange.com/q/132045) In both cases the size is larger than 32 bytes, so you'd need to pad up to 64. Not sure if that applies here though... – Jorn Vernee May 24 '18 at 12:40
  • FWIW, I got instance size 56 bytes, with 4 lost due to next object alignment in 32 bit and 0 lost in 64 bit. – Michael May 24 '18 at 12:55
  • @Michael point being that it does *not* have to be power of two, right? I was working on an example to prove that to JornVernee – Eugene May 24 '18 at 12:56
  • You know there’s something wrong if you don’t see the array length somewhere in the object header… – Holger May 24 '18 at 16:29
  • @Holger :) oh my! did not even notice that, what an idiot... thank you! – Eugene May 25 '18 at 08:12

1 Answers1

6

Instance size: 64 bytes is calculated for the current VM configuration, but you explicitly specify different (incompatible) Layouter.

The difference between actual size (calculated with Instrumentation.getObjectSize) and the expected size (calculated by Layouter) will be treated as loss due to the next object alignment.

See ClassLayout.java

apangin
  • 92,924
  • 10
  • 193
  • 247
  • one minor question still, shouldn't the explicit Layouter still pad to 8 bytes alignment? – Eugene May 25 '18 at 08:16
  • @Eugene I'm not sure what you mean. VM tells "this object currently occupies 64 bytes in heap", and Layouter tries to explain where these 64 bytes are from. When you choose a Layouter from a different VM configuration, you'll definitely get confusing results, since it cannot reasonably explain extra bytes. I don't know why instantiation of an arbitrary Layouter is ever possible in JOL - probably this is an API bug. – apangin May 25 '18 at 09:24
  • I don't see that as a bug at all; what if I want to find the layout of an object without having access to a particular platform? Like `x86_32`? What I actually meant is that the explicit layout computes size as `52 bytes`, I was really expecting saying later : `4 bytes` padding - instance size = `56 bytes` *instead* of giving me the *real* size. I have not asked for the real platform size to begin with. Or put it other way : what would the result be for a *real* x86_32 bit for the first example? – Eugene May 25 '18 at 09:30
  • 1
    @Eugene OK. What I see is that ClassLayout takes the real size of an instance computed for currently running VM, disregarding the data model of given layouter. To me it looks like inconsistency anyway. I suggest to open an issue against JOL. – apangin May 25 '18 at 09:51
  • i initially wanted to, so thank you for confirming this – Eugene May 25 '18 at 09:55