From: Steve B. <ste...@us...> - 2006-06-28 02:06:20
|
Update of /cvsroot/jikesrvm/MMTk/src/org/mmtk/plan/generational In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv1974/src/org/mmtk/plan/generational Modified Files: Gen.java Log Message: Second part of fix to #1511447. In a heavily mutating, but non-allocating context, it is possible that generational collectors will exhaust the available virtual memory for metadata through the generation of a large number of remembered set entries. Since there is no allocation, there are no checks for GC. GC cannot be triggered from within a write barrier, so there's a problem. Fortunately this problem was solved years ago for RefCount et al by introducing the idea of asyncrhonous GC, which allows the barrier initiate an "asynchronous" GC when space is low. The GC is performed at the next GC safe point (not within the barrier). The change required to make this work for the generational collectors was trivial. Index: Gen.java =================================================================== RCS file: /cvsroot/jikesrvm/MMTk/src/org/mmtk/plan/generational/Gen.java,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Gen.java 21 Jun 2006 07:38:14 -0000 1.5 --- Gen.java 28 Jun 2006 02:06:17 -0000 1.6 *************** *** 173,178 **** public final boolean poll(boolean mustCollect, Space space) throws LogicallyUninterruptiblePragma { ! if (getCollectionsInitiated() > 0 || !isInitialized() || ! space == metaDataSpace) return false; --- 173,177 ---- public final boolean poll(boolean mustCollect, Space space) throws LogicallyUninterruptiblePragma { ! if (getCollectionsInitiated() > 0 || !isInitialized()) return false; *************** *** 184,187 **** --- 183,194 ---- META_DATA_FULL_THRESHOLD; if (mustCollect || heapFull || nurseryFull || metaDataFull) { + if (space == metaDataSpace) { + /* In general we must not trigger a GC on metadata allocation since + * this is not, in general, in a GC safe point. Instead we initiate + * an asynchronous GC, which will occur at the next safe point. + */ + setAwaitingCollection(); + return false; + } required = space.reservedPages() - space.committedPages(); if (space == nurserySpace || |