Master Thesis on Shenandoah

Roman Kennke rkennke at redhat.com
Wed Nov 8 15:33:34 UTC 2017


Am 08.11.2017 um 16:14 schrieb Christine Flood:
> Roman wrote:
>
>     "Yes. Then we might be lucky and squeeze it in a leftover word from
> alignment or squeeze it into the gap left by the compressed Klass* (for
> non-arrays) or such."
>
> At the cost of a significantly more expensive read barrier.  My guess is
> that it would add a minimum of a shift and an add.
No. Well, kinda. We would compress the fwd ptr just like any other oop, 
at the same cost.
The Klass* leaves 32bit gap, but only for instances, not for arrays. 
This means we'd have to conditionally generate different barriers 
depending on our knowledge of the object: 1. for instances, read fwdptr 
from klass gap 2. for arrays, read fwdptr from elsewhere 3. for unknown 
generate conditional read-barrier to figure it out at runtime (I expect 
this to be rare). All in all, I doubt it's worth the troubles.

Roman

>
>
>
> On Wed, Nov 8, 2017 at 10:09 AM, Roman Kennke <roman at kennke.org> wrote:
>
>> Am 08.11.2017 um 16:02 schrieb Christine Flood:
>>
>>> Am I reading this correctly?
>>>
>>> Eclipse with 8 byte alignment,compressed oop, and our default of a
>>> preceding forwarding pointer has an overhead of 17%?  That seems
>>> plausible.
>>>
>>> With the above but with uncompressed oops we have an overhead of 30%
>>> without any forwarding pointer?  and our forwarding pointer brings the
>>> overhead up to 47%?   Still seems plausible.
>>>
>>> OK, assuming 8 byte alignment, moving the forwarding pointer uncompressed
>>> into the object seems to buy us nothing and in fact costs us?
>>>
>> I don't see where we could save anything in this scenario.
>>
>>> So, the only win for moving the forwarding pointer with 8 byte alignment
>>> is
>>> to compress the forwarding pointer?
>>>
>> Yes. Then we might be lucky and squeeze it in a leftover word from
>> alignment or squeeze it into the gap left by the compressed Klass* (for
>> non-arrays) or such.
>>
>> Roman
>>
>>
>>
>>> Christine
>>>
>>>
>>>
>>> On Wed, Nov 8, 2017 at 1:35 AM, Dominik Inführ <dominik.infuehr at gmail.com
>>> wrote:
>>>
>>> I added the heap numbers and the data model into a gist:
>>>> https://gist.github.com/dinfuehr/e01b089d2edc3e26324e98ee61752b90. The
>>>> paste.fedoraproject.org-links were only valid for one week.
>>>>
>>>> Dominik
>>>>
>>>> On Tue, Oct 31, 2017 at 7:35 AM, Dominik Inführ <
>>>> dominik.infuehr at gmail.com
>>>> wrote:
>>>>
>>>> Hi,
>>>>> so I've analyzed heap dumps of IntelliJ, Eclipse and NetBeans. I've also
>>>>> repeated the analysis on the JARs in my home directory:
>>>>> https://paste.fedoraproject.org/paste/0C2inj5tDvYZoNq3l-8QfA
>>>>>
>>>>> There are four alternatives:
>>>>> 1) No fwdptr
>>>>> 2) Fwdptr before the object
>>>>> 3) uncompressed fwdptr after object header (first field)
>>>>> 4) compressed fwdptr after object header
>>>>>
>>>>> I've tested these 4 modes with alignment of 8, 16 and 32 bytes and
>>>>> compressed/uncompressed oops. All sizes in the link are relative to
>>>>>
>>>> 8-byte
>>>>
>>>>> alignment, compressed oops and no fwdptr.
>>>>>
>>>>> Here is the DataModel I used for measuring sizes:
>>>>> https://paste.fedoraproject.org/paste/vWp--180wJzeERL47Eueeg
>>>>>
>>>>> Surprising for me was that there are no space savings for a compressed
>>>>> fwdptr when using uncompressed oops (for the classes in my JAR files).
>>>>>
>>>> The
>>>>
>>>>> reason for that is that each superclass (in this case java.lang.Object)
>>>>>
>>>> is
>>>>
>>>>> aligned to the oop size (16 bytes header + 4 bytes fwdptr + 4 bytes
>>>>>
>>>> padding
>>>>
>>>>> = 16 bytes header + 8 bytes fwdptr).
>>>>>
>>>>> HotspotLayouter has options to use that space (takeHierarchyGaps or
>>>>> takeSuperGaps), but they are not activated by default and I couldn't
>>>>> find
>>>>> those options in the JDK. Nevertheless there are some space savings for
>>>>>
>>>> the
>>>>
>>>>> heap dumps because of Arrays: the padding can be used by the
>>>>>
>>>> length-field.
>>>>
>>>>> Do the numbers sound reasonable to you? Should I take heap dumps of
>>>>> other
>>>>> applications as well? Since I basically analyzed 3 IDEs. Heap dump sizes
>>>>> were all about 130MB.
>>>>>
>>>>> Dominik
>>>>>
>>>>> On Wed, Oct 18, 2017 at 10:32 PM, Dominik Inführ <
>>>>> dominik.infuehr at gmail.com> wrote:
>>>>>
>>>>> On Wed, Oct 18, 2017 at 1:06 PM, Aleksey Shipilev <shade at redhat.com>
>>>>>> wrote:
>>>>>>
>>>>>> On 10/16/2017 09:26 PM, Dominik Inführ wrote:
>>>>>>>> I want to give a short update: I've changed JOL a bit such that it
>>>>>>>>
>>>>>>> emits the class/instance-size for
>>>>>>>
>>>>>>>> both the variant with the compressed fwdptr and the uncompressed
>>>>>>>>
>>>>>>> fwdptr. All I did was to reuse the
>>>>>>>
>>>>>>>> HotspotLoader from JOL with a new data model subclassed from
>>>>>>>>
>>>>>>> X86_64_COOPS_Fwdptr_DataModel. The data
>>>>>>>
>>>>>>>> model adds either 4 (for compressed fwdptr) or 8 (for the
>>>>>>>>
>>>>>>> uncompressed) to the header size.
>>>>>>>
>>>>>>> Ah, there is a caveat: extending the header size is probably not in
>>>>>>>
>>>>>> line
>>>>> with what we would do with
>>>>>>> fwdptr storage. That is, extending the header would need to include
>>>>>>> the
>>>>>>> internal alignments for
>>>>>>> fwdptr, e.g. this is wrong:
>>>>>>>
>>>>>>> 0:  [header]
>>>>>>> 12: [8-byte fwdptr] // alignment is broken
>>>>>>>
>>>>>>> I think we have to simulate the "injection" of fwdptr as the field in
>>>>>>> java/lang/Object to make it
>>>>>>> the subject of alignment constraints. So, there are four cases:
>>>>>>>
>>>>>>>    a. No fwdptr
>>>>>>>    b. 8-byte fwdptr before the object (that can indeed be modelled with
>>>>>>> adding +8 to header)
>>>>>>>    c. 8-byte fwdptr as the field
>>>>>>>    d. 4-byte fwdptr as the field
>>>>>>>
>>>>>>> So I guess I've tested the cases a), b) and d).
>>>>>> I actually thought about c) but disregarded it, since it was harder to
>>>>>> implement :D but also because it could only make things worse. But I
>>>>>>
>>>>> guess
>>>>> it might be beneficial for ObjectAlignmentInBytes > 8. It may already be
>>>>>> good enough to simulate this field by writing the header something like
>>>>>> this:
>>>>>>
>>>>>> int headerSize() { return align(super.headerSize(), 8) + 8; }
>>>>>>
>>>>>> I guess I really should get some numbers for compressed/uncompressed
>>>>>>
>>>>> oops
>>>>> for different alignments.
>>>>>>
>>>>>> With this I can compare class/instance-sizes for e.g. all the JARs in
>>>>>>> my home directory (about
>>>>>>>
>>>>>>>> 114,000 classes). I just summed up all class sizes for each of the 3
>>>>>>>>
>>>>>>> variants (no fwdptr,
>>>>>>>
>>>>>>>> uncompressed fwdptr, compressed fwdptr), each class is counted once:
>>>>>>>>
>>>>>>> Classes with an uncompressed
>>>>>>>
>>>>>>>> fwdptr have in total 22.7% overhead over those same classes with no
>>>>>>>>
>>>>>>> fwdptr (11.4% for compressed
>>>>>>>
>>>>>>>> fwdptr's). 70% of the classes seem to be smaller with a compressed
>>>>>>>>
>>>>>>> fwdptr compared to the same class
>>>>>>>
>>>>>>>> with an uncompressed fwdptr.
>>>>>>>>
>>>>>>> Okay, nice piece of data! Now we need to figure out what are the most
>>>>>>> popular object shapes around
>>>>>>> real Java applications -- try to process some heapdumps for the Java
>>>>>>> applications you have? Parsing
>>>>>>> Maven Central is overkill at this point.
>>>>>>>
>>>>>>> I was actually hoping that you would tell me this is overkill ;) I
>>>>>> will
>>>>>> try to find some and take a heap dump of them.
>>>>>>
>>>>>> Thank you very much for the feedback!
>>>>>>
>>>>>> Dominik
>>>>>>
>>>>>>
>>>>>> -Aleksey
>>>>>>>
>>>>>>>



More information about the shenandoah-dev mailing list