RFR: 8069367: assert(_nextMarkBitMap->isMarked((HeapWord*) obj)) failed
bengt.rutisson at oracle.com
Wed Mar 18 14:02:50 UTC 2015
On 2015-03-17 22:23, Kim Barrett wrote:
> On Mar 13, 2015, at 1:51 PM, Kim Barrett <kim.barrett at oracle.com> wrote:
>> On Mar 13, 2015, at 4:45 AM, Bengt Rutisson <bengt.rutisson at oracle.com> wrote:
>>> Another alternative would be to let initial marking note all humongous objects that were live after initial mark. Then we can just make sure that early reclaim does not reclaim any of those humongous objects while marking is active. That should be a pretty simple fix that can be backported if necessary.
>> Bengt and I talked about this some more; I’m going to have a look at the code for this, as it seems likely better.
> Here’s a new webrev, following Bengt’s suggestion.
The change looks good to me. One minor nit. The command line for the
@run command in the test is not aligned:
30 * @run main/othervm -XX:+UseG1GC -Xss32m -Xmx128m
31 * -XX:+UnlockExperimentalVMOptions
32 * -XX:+G1EagerReclaimHumongousObjects
33 * -XX:+G1EagerReclaimHumongousObjectsWithStaleRefs
34 * TestGreyReclaimedHumongousObjects 1048576 90
> No incremental webrev, since the approach (and so the changes) are entirely different.
> As a reminder, the scenario we are dealing with is
> (1) A humongous object H is marked and added to the mark stack.
> (2) An evacuation pause determines H is no longer live, and reclaims
> it. This occurs before concurrent marking has gotten around to
> processing the mark stack entry for H.
> (3) Concurrent marking processes the mark stack entry for H,
> attempting to scan the now dead object.
> The new approach is to create a set of candidates at the start of the collection
> pause, remove candidates as they are reached from roots or from the young
> generation, and release any remaining candidates with empty remsets. (This
> is similar to before.)
> The difference is in how we create the set of candidates. Previously, all humongous
> objects satisfying certain type restrictions and remset size limits were treated as
> candidates. Now, when concurrent marking is in progress, we also exclude from
> the initial candidate set any objects that were live at the start of marking, determined
> by comparing the object against its region’s TAMS value. Such objects are excluded
> because they must be scanned because of SATB.
> Because we now exclude objects that were live at start of marking when marking
> is in progress, the scenario we’re trying to deal with simply can’t occur. If H gets
> marked and added to the mark stack, it was necessarily live at start of mark; the
> marking process filters out objects that were allocated since marking started, e.g.
> we allocate black while marking, so such objects aren’t added to the mark stack.
> Since the objects that can be added to the mark stack are excluded from the
> reclaim candidate set, the problematic situation cannot arise.
> Since I was rewriting the relevant code anyway, I've also changed the type restriction
> for candidacy. Previously it was !is_objArray() and has been changed to is_typeArray().
> This addresses https://bugs.openjdk.java.net/browse/JDK-8072598.
> Note that we can’t yet eagerly reclaim humongous objects containing references,
> because there are remset entries from such objects that need to be dealt with.
> [I think this is (part of?) https://bugs.openjdk.java.net/browse/JDK-8071913.]
> JPRT, Aurora ad hoc GC Nightly and other tests with -XX:+UseG1GC
More information about the hotspot-gc-dev