Skip to content

Commit dd7b74a

Browse files
committed
Cleanup after tests to avoid OOME: Metaspace in fast-run testOnly sequence
After these changes, this project no longer exhibits the problems discussed in sbt/sbt#2056
1 parent 99e6812 commit dd7b74a

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

build.sbt

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ def commonSettings: Seq[Setting[_]] = Def.settings(
3030
inCompileAndTest(scalacOptions in console --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint")),
3131
publishArtifact in Compile := true,
3232
publishArtifact in Test := false,
33-
parallelExecution in Test := false
33+
parallelExecution in Test := false,
34+
testOptions in Test += {
35+
val log = streams.value.log
36+
Tests.Cleanup { loader => cleanupTests(loader, log) }
37+
}
3438
)
3539

3640
val mimaSettings = Def settings (
@@ -275,3 +279,22 @@ inThisBuild(Seq(
275279

276280
def inCompileAndTest(ss: SettingsDefinition*): Seq[Setting[_]] =
277281
Seq(Compile, Test) flatMap (inConfig(_)(Def.settings(ss: _*)))
282+
283+
284+
// TODO move into sbt-house-rules?
285+
def cleanupTests(loader: ClassLoader, log: sbt.internal.util.ManagedLogger): Unit = {
286+
// shutdown Log4J to avoid classloader leaks
287+
try {
288+
val logManager = Class.forName("org.apache.logging.log4j.LogManager")
289+
logManager.getMethod("shutdown").invoke(null)
290+
} catch {
291+
case _: Throwable =>
292+
log.warn("Could not shut down Log4J")
293+
}
294+
// Scala Test loads property bundles, let's eagerly clear then from the internal cache
295+
// TODO move into SBT itself?
296+
java.util.ResourceBundle.clearCache(loader)
297+
// Scala Test also starts TimerThreads that it doesn't eagerly cancel. This can weakly retain
298+
// metaspace until a full GC.
299+
System.gc()
300+
}

0 commit comments

Comments
 (0)