javaarraysjvmjvm-hotspotjol

Java primitive array layout in memory


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?


Solution

  • 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