Field layout code starts laying out the instance fields block at super-klass instance boundary. This quirk makes the classes like this:
public static class A {
private boolean b;
}
public static class B extends A {
private boolean b;
}
public static class C extends B {
private boolean b;
}
...to be laid out like this:
C object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 12 (object header)
12 1 boolean A.b N/A
13 3 (alignment/padding gap)
16 1 boolean B.b N/A
17 3 (alignment/padding gap)
20 1 boolean C.b N/A
21 3 (loss due to the next object alignment)
Space losses: 6 bytes internal + 3 bytes external = 9 bytes total
It seems legal to lay out the fields like this instead:
C object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 12 (object header)
12 1 boolean A.b N/A
13 1 boolean B.b N/A
14 1 boolean C.b N/A
15 1 (loss due to the next object alignment)
Space losses: 0 bytes internal + 1 bytes external = 1 bytes total
Which saves us 8 bytes per instance. This is layout change is OK, since we don't need booleans to be aligned by 4 (in fact, if we put all three booleans in the same class, they will be laid out exactly like this, side-to-side). The only reason we've got alignment is because the superclass instance size was the multiple of 4.
public static class A {
private boolean b;
}
public static class B extends A {
private boolean b;
}
public static class C extends B {
private boolean b;
}
...to be laid out like this:
C object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 12 (object header)
12 1 boolean A.b N/A
13 3 (alignment/padding gap)
16 1 boolean B.b N/A
17 3 (alignment/padding gap)
20 1 boolean C.b N/A
21 3 (loss due to the next object alignment)
Space losses: 6 bytes internal + 3 bytes external = 9 bytes total
It seems legal to lay out the fields like this instead:
C object internals:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 12 (object header)
12 1 boolean A.b N/A
13 1 boolean B.b N/A
14 1 boolean C.b N/A
15 1 (loss due to the next object alignment)
Space losses: 0 bytes internal + 1 bytes external = 1 bytes total
Which saves us 8 bytes per instance. This is layout change is OK, since we don't need booleans to be aligned by 4 (in fact, if we put all three booleans in the same class, they will be laid out exactly like this, side-to-side). The only reason we've got alignment is because the superclass instance size was the multiple of 4.
- duplicates
-
JDK-8237767 Field layout computation overhaul
- Resolved
- relates to
-
JDK-7007564 Align non-static fields size on byte instead of wordSize
- Closed
-
JDK-8024913 Subclasses are not using the super-class space gaps to place the fields
- Closed