RFR: 8254739: G1: Optimize evacuation failure for regions with few failed objects [v7]

Thomas Schatzl tschatzl at openjdk.java.net
Fri Sep 10 12:48:08 UTC 2021


On Thu, 26 Aug 2021 10:04:54 GMT, Hamlin Li <mli at openjdk.org> wrote:

>> This is a try to optimize evcuation failure for regions.
>> I record every evacuation failure object per region (by G1EvacuationFailureObjsInHR), and then iterate (which indeed includes compact/sort/iteration) these objects directly in RemoveSelfForwardPtrHRClosure.
>> 
>> I have tested it with following parameters, 
>> 
>> -   -XX:+ParallelGCThreads=1/32/64
>> -   -XX:G1EvacuationFailureALotInterval=1
>> -   -XX:G1EvacuationFailureALotCount=2/10/100/1000/10000/100000
>> 
>> It saves "Remove Self Forwards" time all the time ,and in most condition it saves "Evacuate Collection Set" time. 
>> 
>> It brings some performance degradation when -XX:G1EvacuationFailureALotCount is low, such as *2*. To improve this a little, we can record the number evacuation failure object per region, and not record these objects when the number hit some limit. But I'm not sure if it's necessary to do so, as I think such condition is so extreme to be met in real environment, although I'm not quite sure.
>
> Hamlin Li has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Fix compilation error on windows

Performance is good as is, particularly the Remove self-forwards phase is much much faster now. I added a figure to the CR [here](https://bugs.openjdk.java.net/secure/attachment/96321/20210902-remove-self-forwards-improvement.png). Really nice.

Although there are a few existing abnormalities with this change (not newly introduced, the old code is as bad), see [JDK-8273309](https://bugs.openjdk.java.net/browse/JDK-8273309).

There are a few things that need to be improved:
* we talked about this before, but I do not think putting `G1EvacuationFailureObjsInHR`, which is something only used in evacuation failure, into `HeapRegion`, should be done. At least at the moment, it is almost never used.
* I do not like the use and the implementation of `G1EvacuationFailureObjsInHR`: it recreates something thatt is done better elsewhere (mark stack, DCQS buffer allocator, and in particular in the remembered set cardset allocator) with less features, in a non-fitting style.
Examples are something like reuse of available chunks, concurrent freeing of chunks, automatic resizing of blocks on demand to decrease allocations and potentially other stuff seems something we would really really want.
* as far as I understand the implementation of `G1EvacuationFailureObjsInHR` ;) - there is zero documentation about the basic structure - it seems to allocate quite a lot of memory that is almost never used. Even in the case of evacuation failure it's likely to be almost empty.
`G1EvacuationFailureObjsInHR` seems to basically be a preallocated `ArrayList` of chunks (the `_array_list` member).
Afaict it uses like 1/256 of total heap size (i.e. 0.3%), that's way way too much ( 1 / (256 * sizeof(HeapWord)) * sizeof(pointer); in `G1EvacuationFailureObjsInHR.cpp:86`; the `Array` constructor in `G1EvacuationFailureObjsInHR.hpp:124)) ). We will also get into trouble about startup time about this, I'm sure. That, tbh, alone makes it a no-go if I did not miscalculate.

Let's work on renaming and reusing the infrastructure provided by the remembered set (`G1CardSetAllocator` etc) in `g1CardSetMemory.hpp`.

-------------

PR: https://git.openjdk.java.net/jdk/pull/5181



More information about the hotspot-gc-dev mailing list