From 06a153278f01638d3d7a61ef54f9ae113d198a38 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Sun, 13 Jan 2019 15:18:30 -0800 Subject: [PATCH 1/2] Cleanup cache when CommandExchange shuts down I noticed that sometimes when running scripted tests that I'd run out of metaspace. I believe that this may be due to the caffeine cache leaking classloaders. Regardless, it's a good idea to clear the cache whenever we shutdown the command exchange or reload the state. --- main/src/main/scala/sbt/Main.scala | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/main/src/main/scala/sbt/Main.scala b/main/src/main/scala/sbt/Main.scala index 0ae325509..8241d5b50 100644 --- a/main/src/main/scala/sbt/Main.scala +++ b/main/src/main/scala/sbt/Main.scala @@ -16,17 +16,18 @@ import sbt.Project.LoadAction import sbt.compiler.EvalImports import sbt.internal.Aggregation.AnyKeys import sbt.internal.CommandStrings.BootCommand +import sbt.internal._ import sbt.internal.inc.ScalaInstance import sbt.internal.util.Types.{ const, idFun } -import sbt.internal.util.complete.Parser import sbt.internal.util._ -import sbt.internal._ +import sbt.internal.util.complete.Parser import sbt.io.syntax._ import sbt.io.{ FileTreeDataView, IO } import sbt.util.{ Level, Logger, Show } import xsbti.compile.CompilerCache import scala.annotation.tailrec +import scala.concurrent.ExecutionContext import scala.util.control.NonFatal /** This class is the entry point for sbt. */ @@ -85,13 +86,15 @@ final class ConsoleMain extends xsbti.AppMain { object StandardMain { private[sbt] lazy val exchange = new CommandExchange() - import scalacache._ import scalacache.caffeine._ - private[sbt] lazy val cache: Cache[Any] = CaffeineCache[Any] + private[sbt] lazy val cache: scalacache.Cache[Any] = CaffeineCache[Any] - private[sbt] val shutdownHook = new Thread(() => { - exchange.shutdown - }) + private[this] val closeRunnable: Runnable = () => { + cache.close()(scalacache.modes.sync.mode) + cache.close()(scalacache.modes.scalaFuture.mode(ExecutionContext.global)) + exchange.shutdown() + } + private[sbt] val shutdownHook = new Thread(closeRunnable) def runManaged(s: State): xsbti.MainResult = { val previous = TrapExit.installManager() @@ -106,7 +109,7 @@ object StandardMain { try { MainLoop.runLogged(s) } finally { - exchange.shutdown + closeRunnable.run() if (hooked) { Runtime.getRuntime.removeShutdownHook(shutdownHook) } From ba3ff8198d10ac4d6db2a7d43bb53f5ed6880065 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Wed, 30 Jan 2019 10:31:34 -0800 Subject: [PATCH 2/2] Remove unneeded parens in Definition.scala --- main/src/main/scala/sbt/internal/server/Definition.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/internal/server/Definition.scala b/main/src/main/scala/sbt/internal/server/Definition.scala index 4f1935175..038eabc4c 100644 --- a/main/src/main/scala/sbt/internal/server/Definition.scala +++ b/main/src/main/scala/sbt/internal/server/Definition.scala @@ -227,7 +227,7 @@ private[sbt] object Definition { val cacheFile = compileIncSetup.value.cacheFile.getAbsolutePath val useBinary = enableBinaryCompileAnalysis.value val s = state.value - s.log.debug(s"analysis location ${(cacheFile -> useBinary)}") + s.log.debug(s"analysis location ${cacheFile -> useBinary}") import scalacache.modes.sync._ updateCache(StandardMain.cache)(cacheFile, useBinary) }