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