@@ -231,31 +231,30 @@ private boolean collectImpl(GCCause cause, boolean forceFullGC) {
231231 private boolean doCollectImpl (GCCause cause , boolean forceFullGC ) {
232232 CommittedMemoryProvider .get ().beforeGarbageCollection ();
233233
234- completeCollection = forceFullGC || policy .shouldCollectCompletely (false );
235- boolean outOfMemory = doCollectOnce (cause );
236- if (!completeCollection && (outOfMemory || policy .shouldCollectCompletely (true ))) {
237- completeCollection = true ;
238- outOfMemory = doCollectOnce (cause );
234+ boolean incremental = HeapParameters .Options .CollectYoungGenerationSeparately .getValue () ||
235+ (!forceFullGC && !policy .shouldCollectCompletely (false ));
236+ boolean outOfMemory = false ;
237+ if (incremental ) {
238+ outOfMemory = doCollectOnce (cause , false , false );
239+ }
240+ if (!incremental || outOfMemory || forceFullGC || policy .shouldCollectCompletely (true )) {
241+ outOfMemory = doCollectOnce (cause , true , incremental );
239242 }
240243
241- CommittedMemoryProvider .get ().afterGarbageCollection (completeCollection );
244+ CommittedMemoryProvider .get ().afterGarbageCollection ();
242245 return outOfMemory ;
243246 }
244247
245- private boolean doCollectOnce (GCCause cause ) {
248+ private boolean doCollectOnce (GCCause cause , boolean complete , boolean followsIncremental ) {
249+ assert !followsIncremental || complete : "An incremental collection cannot be followed by another incremental collection" ;
250+ completeCollection = complete ;
251+
246252 accounting .beforeCollection ();
247253 policy .onCollectionBegin (completeCollection );
248254
249255 Timer collectionTimer = timers .collection .open ();
250256 try {
251- if (completeCollection ) {
252- if (HeapParameters .Options .CollectYoungGenerationSeparately .getValue ()) {
253- scavenge (true );
254- }
255- scavenge (false );
256- } else {
257- scavenge (true );
258- }
257+ scavenge (!complete , followsIncremental );
259258 } finally {
260259 collectionTimer .close ();
261260 }
@@ -487,15 +486,15 @@ public boolean isCompleteCollection() {
487486 }
488487
489488 /** Scavenge, either from dirty roots or from all roots, and process discovered references. */
490- private void scavenge (boolean fromDirtyRoots ) {
489+ private void scavenge (boolean incremental , boolean followingIncremental ) {
491490 GreyToBlackObjRefVisitor .Counters counters = greyToBlackObjRefVisitor .openCounters ();
492491 try {
493492 Timer rootScanTimer = timers .rootScan .open ();
494493 try {
495- if (fromDirtyRoots ) {
494+ if (incremental ) {
496495 cheneyScanFromDirtyRoots ();
497496 } else {
498- cheneyScanFromRoots ();
497+ cheneyScanFromRoots (followingIncremental );
499498 }
500499 } finally {
501500 rootScanTimer .close ();
@@ -561,7 +560,7 @@ private void cleanRuntimeCodeCache() {
561560 }
562561 }
563562
564- private void cheneyScanFromRoots () {
563+ private void cheneyScanFromRoots (boolean followingIncremental ) {
565564 Timer cheneyScanFromRootsTimer = timers .cheneyScanFromRoots .open ();
566565 try {
567566 /* Take a snapshot of the heap so that I can visit all the promoted Objects. */
@@ -572,6 +571,15 @@ private void cheneyScanFromRoots() {
572571 */
573572 prepareForPromotion ();
574573
574+ if (followingIncremental ) {
575+ /*
576+ * We just finished an incremental collection, so we will not be able to reclaim any
577+ * young objects and do not need to copy them (and do not want to age or tenure them
578+ * in the process). We still need to scan them for roots into the old generation.
579+ */
580+ HeapImpl .getHeapImpl ().getYoungGeneration ().emptyFromSpacesIntoToSpaces ();
581+ }
582+
575583 /*
576584 * Make sure all chunks with pinned objects are in toSpace, and any formerly pinned
577585 * objects are in fromSpace.
0 commit comments