RFR (9) 8185133: Reference pending list root might not get marked

Erik Osterlund erik.osterlund at oracle.com
Fri Jul 28 17:20:02 UTC 2017

Hi Roman,

> On 28 Jul 2017, at 16:53, Roman Kennke <rkennke at redhat.com> wrote:
> Hi Mikael,
> I don't really understand what the problem is. The WR ends up on the
> RPL, with its referent cleared, i.e. no longer pointing to the SR? But
> we want to keep the SR alive?

No. The WR gets promoted to old during the initial mark evacuation as it was strongly reachable by a SR in young. The referent of the WR died, and therefore it gets discovered. The assumption is then that since it was strongly reachable from the SR in young, the WR will be found during concurrent marking due to SATB. This is normally a safe assumption.

However, just before finishing the initial mark pause and letting concurrent marking start trace through the heap, soft references may change strength to suddenly become weak. Therefore, the WR in old never gets marked during concurrent marking unless the GC is made aware of the existence of this new strong edge to the pending list head.

This is a problem, because the pending list was in this scenario exposed to Java land through the pending list head, without the concurrent marking knowing about it, violating GC completeness.

> Also, Universe::oops_do() already marks the RPL head, doesn't it?

Reference processing is done after root processing. Therefore the edge to the pending list, created during reference processing, is not yet made available at that time.

Hope that made sense.


> Roman
>> Hi all,
>> Please review this fix to a tricky reference processing / conc marking
>> bug affecting G1 in 9.
>> The bug occurs when a weak reference WR is promoted to old and
>> discovered during an initial mark pause. The WR is the referent of a
>> soft reference SR. The concurrent reference processor determines that
>> SR should be treated as a weak reference due to shortage of memory and
>> now WR is reachable only from the reference pending list but not
>> explicitly marked in the bitmap since objects promoted during the
>> initial mark pause are not marked immediately.
>> The reason we are not saved by the SATB pre-barrier here is that
>> clearing of the referent field of a reference object does not trigger
>> the pre-barrier (and that would kind of defeat its purpose).
>> Before JDK-8156500 this worked because the reference pending list was
>> a static field in the Reference class and the reference class was
>> scanned during concurrent marking, so we would never lose track of the
>> pending list head.
>> My suggested fix is to explicitly mark the reference pending list head
>> oop during initial mark, after the reference enqueue phase.
>> This mirrors how other roots are handled in initial mark, see
>> G1Mark::G1MarkPromotedFromRoots.
>> Webrev: http://cr.openjdk.java.net/~mgerdin/8185133/webrev.0
>> Bug: https://bugs.openjdk.java.net/browse/JDK-8185133
>> Testing: JPRT, tier2-5 gc tests, a LOT of runs of the failing test.
>> Many thanks to Kim and Erik Ö for discussions around this issue!
>> Thanks
>> /Mikael

More information about the hotspot-gc-dev mailing list