Run a manual GC after clearing the in-memory graph from a `--keep_state_after_build` command.
Same purpose as unknown commit except for cases where the previous build kept state.
PiperOrigin-RevId: 550048302
Change-Id: I6bf3ef26edfcd9f63ff2f71790dd28f15de9d714
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java
index 4cb7842..47b55e0 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java
@@ -55,6 +55,7 @@
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.pkgcache.PathPackageLocator;
+import com.google.devtools.build.lib.profiler.GoogleAutoProfilerUtils;
import com.google.devtools.build.lib.profiler.Profiler;
import com.google.devtools.build.lib.profiler.ProfilerTask;
import com.google.devtools.build.lib.repository.ExternalPackageHelper;
@@ -123,6 +124,8 @@
private boolean trackIncrementalState = true;
private boolean evaluatorNeedsReset = false;
+ private boolean lastCommandKeptState = false;
+ private boolean needGcAfterResettingEvaluator = false;
private final AtomicInteger outputDirtyFiles = new AtomicInteger();
private final ArrayBlockingQueue<String> outputDirtyFilesExecPathSample =
@@ -258,6 +261,15 @@
// or if the graph doesn't have edges, so that a fresh graph can be used.
resetEvaluator();
evaluatorNeedsReset = false;
+ if (needGcAfterResettingEvaluator) {
+ // Collect weakly reachable objects to avoid resurrection. See b/291641466.
+ try (var profiler =
+ GoogleAutoProfilerUtils.logged(
+ "manual GC to clean up from --keep_state_after_build command")) {
+ System.gc();
+ }
+ needGcAfterResettingEvaluator = false;
+ }
}
super.sync(
eventHandler,
@@ -389,13 +401,17 @@
}
// Now check if it is necessary to wipe the previous state. We do this if either the previous
- // or current incrementalStateRetentionStrategy requires the build to have been isolated.
+ // or current command requires the build to have been isolated.
if (oldValueOfTrackIncrementalState != trackIncrementalState) {
logger.atInfo().log("Set incremental state to %b", trackIncrementalState);
evaluatorNeedsReset = true;
} else if (!trackIncrementalState) {
evaluatorNeedsReset = true;
}
+ if (evaluatorNeedsReset && lastCommandKeptState) {
+ needGcAfterResettingEvaluator = true;
+ }
+ lastCommandKeptState = keepStateAfterBuild;
}
@Override