JDK-8024913 : Subclasses are not using the super-class space gaps to place the fields
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 8
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: generic
  • Submitted: 2013-09-17
  • Updated: 2020-02-11
  • Resolved: 2020-01-24
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdResolved
Related Reports
Duplicate :  
Relates :  
Description
Field layout code makes no use of the super-class gaps. Which means if we have the space in superclass area, we don't use it. For example:

    public static class A {
        long f;
    }

    public static class B extends A {
        long f;
    }

    public static class C extends B {
        long f;
        int a;
    }

...is laid out like this:

  jol.Main_05_InheritanceBarrier.C object internals:
   OFFSET  SIZE  TYPE DESCRIPTION                    VALUE
        0    12       (object header)
       12     4       (alignment/padding gap)
       16     8  long A.f                            N/A
       24     8  long B.f                            N/A
       32     8  long C.f                            N/A
       40     4   int C.a                            N/A
       48     4       (loss due to the next object alignment)
  Space losses: 4 bytes internal + 4 bytes external = 8 bytes total

It seems legal to lay out the fields like this (i.e. move the C.a up to fill the gap):

  jol.Main_05_InheritanceBarrier.C object internals:
   OFFSET  SIZE  TYPE DESCRIPTION                    VALUE
        0    12       (object header)
       12     4   int C.a                            N/A
       16     8  long A.f                            N/A
       24     8  long B.f                            N/A
       32     8  long C.f                            N/A
  Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

That saves 8 bytes per instance. While this is arguably hard to do with current field layout code. By Java rules, C.a is not visible in A anyway, and there is no legal way to hijack its value. Am I overlooking something?


Comments
Reopening since the mentioned "Jiangli's analysis for JDK-7007564" is not nearly as complete as the analysis performed here. Since the analysis in JDK-7007564 is very basic, and also because the results of the analysis in this issue marks better benefits, it seems incorrect to WNF this issue.
10-02-2014

Closing as WNF based on Jiangli's analysis for JDK-7007564.
10-02-2014

Updated data on the set of heapdumps we have internally, now with the arrays included. These heaps dumps still raise the question about representativity. There were also a few quirks in the processing scripts which yield the underestimated metrics. This is why the data is slightly different even though arrays are not affected by this RFE. For this change, we have 0.03% average and 0.12% max improvement in heap occupancy. The summary quantiles are: 0.000% Min 0.010% 1st Qu. 0.022% Median 0.028% Mean 0.041% 3rd Qu. 0.121% Max.
18-10-2013

This RFE implicitly resolves JDK-8024912.
18-10-2013

I have also munched through the set of heap dumps we have internally. These heaps dumps raise the question about representativity, but still. Note that the data below is the *underestimate*, because these are counting only the classes, not the arrays. Large arrays dominate the heap, taking the class improvements down. For this change, we have 0.02% average and 0.05% max improvement in heap occupancy on average. The summary quantiles are: 0.000% Min. 0.008% 1st Qu. 0.018% Median 0.020% Mean 0.032% 3rd Qu. 0.054% Max.
10-10-2013

"Java Field Layouts: Qualitative Study on Maven Central" http://cr.openjdk.java.net/~shade/papers/2013-shipilev-fieldlayout-latest.pdf This report estimates up to 2.4% of real-world classes are benefiting from this improvement, with average 10% reduction in memory footprint per class.
03-10-2013

Great, thanks!
17-09-2013

Yes, I do; I will tabulate this later, when the tooling is in the open. Also, I want to have a larger corpus of Java classes, not just rt.jar.
17-09-2013

Thanks, I've just added above comment to JDK-8024912. BTW, Alekesy, do you have the total number for memory gaps caused by such gap in rt.jar? That will be very useful. Thanks.
17-09-2013

Jiangli, I think this comment should go to JDK-8024912. The issue at hand talks about reusing the gaps not only at the end of the superclass, but any other gap found there. See the example where C.a jumped all the way across both A and B instance fields. I have seen lots of classes in rt.jar exhibiting the layouts like these, mostly because of 1-byte booleans.
17-09-2013

There was a similar proposal suggested by Vladimir Kozlov. Experiments using the rt.jar seemed to indicate the gaps between the first non-static field in child class and the last non-static field in superclass are not common cases. Please see JDK-7007564 for details.
17-09-2013