request for review (m) - 6858496
John Coomes
John.Coomes at sun.com
Thu Oct 15 23:26:05 UTC 2009
Jon Masamitsu (Jon.Masamitsu at Sun.COM) wrote:
> Fixed 6858496: Clear all SoftReferences before an out-of-memory due to
> GC overhead limit.
>
> Also did some tuning of the policy for out-of-memory due to GC overhead to
> make it more restrictive. A successful scavenge will reset the count
> on consecutive GC's needed to exceed the GC overhead limit.
+1 on that change :-).
> This is intended for HSX17.
>
> http://cr.openjdk.java.net/~jmasa/6858496/webrev.00/
The soft ref clearing changes still leave a window where softrefs may
not be cleared. The clearing is done on gc N, but the OOME is thrown
after gc N+1.
The problem is that the decision to throw OOME because of gc overhead
is made before the GC, and once made, the GC is not actually done--it
simply returns NULL which ends up throwing OOME. The decision has to
be made after a GC in which all softrefs were cleared.
Since clearing softrefs is a language requirement, I think we need a
contract between the policy and the collectors regarding softrefs.
Imagine the size policy has two fields:
_should_clear_all_softrefs - set to true when policy wants softrefs
cleared; set to false by gc after it clears all softrefs.
_all_softrefs_clear - whether the just-completed gc cleared all
softrefs. This is set to true whenever a gc clears all softrefs, and
set to false each time gc returns to the mutator. For example, in the
ParallelScavengeHeap case the latter would be done toward the end of
mem_allocate() where it returns op.result().
Each full gc would check policy->should_clear_all_softrefs() and if
true, clear them. Otherwise, it would use the existing means of
deciding whether to clear all softrefs.
Whenever a collector clears all soft refs, it calls something like
policy->cleared_all_softrefs() to record that fact.
cleared_all_softrefs() is trivial:
cleared_all_softrefs() {
_should_clear_all_softrefs = false;
_all_softrefs_clear = true;
}
After a gc, the decision whether to throw OOME because of the overhead
limit would have to check that softrefs had been cleared. This omits
some details, but ...
if (op.result() != NULL) {
if (gc exceeded overhead limits) {
if (policy->all_softrefs_clear()) {
... reset overhead limit fields ...
... turn op.result() into a filler object ...
return NULL; // Cause an OOME.
} else {
// clear softrefs on next full gc
policy->set_should_clear_all_softrefs(true);
}
}
} else {
... reset overhead limit fields ...
}
-John
More information about the hotspot-gc-dev
mailing list