From 0215226f4d972a9c10356d7350a73356e5dcb1dc Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Fri, 13 Jul 2018 15:25:44 +1000 Subject: [PATCH] Cleanup after tests to avoid OOME: Metaspace in fast-run testOnly sequence After these changes, this project no longer exhibits the problems discussed in https://github.com/sbt/sbt/issues/2056 --- build.sbt | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 4e812dcc..e5329521 100644 --- a/build.sbt +++ b/build.sbt @@ -29,7 +29,11 @@ def commonSettings: Seq[Setting[_]] = Seq( }, publishArtifact in Compile := true, publishArtifact in Test := false, - parallelExecution in Test := false + parallelExecution in Test := false, + testOptions in Test += { + val log = streams.value.log + Tests.Cleanup { loader => cleanupTests(loader, log) } + } ) val mimaSettings = Def settings ( @@ -232,3 +236,21 @@ def customCommands: Seq[Setting[_]] = Seq( state } ) + +// TODO move into sbt-house-rules? +def cleanupTests(loader: ClassLoader, log: sbt.internal.util.ManagedLogger): Unit = { + // shutdown Log4J to avoid classloader leaks + try { + val logManager = Class.forName("org.apache.logging.log4j.LogManager") + logManager.getMethod("shutdown").invoke(null) + } catch { + case _: Throwable => + log.warn("Could not shut down Log4J") + } + // Scala Test loads property bundles, let's eagerly clear then from the internal cache + // TODO move into SBT itself? + java.util.ResourceBundle.clearCache(loader) + // Scala Test also starts TimerThreads that it doesn't eagerly cancel. This can weakly retain + // metaspace until a full GC. + System.gc() +} \ No newline at end of file