mirror of https://github.com/sbt/sbt.git
This commit adds a new ClassLoaderCache that builds on the ClassLoaderCache that is present in zinc (and can be used to build an instance of the zinc ClassLoaderCache to preserve compatibility). It differs from the zinc classloader cache that it does not use direct SoftReferences to classloaders. Instead, we create a wrapper loader that can't load any classes and just delegates to its parent. This allows us to add a thread that reaps the soft reference to the wrapper loader. Crucially, we add a custom SoftReference class that has a strong reference to the underlying classloader. This allows us to call close on the strong reference. The one issue with this approach is that we can't rescue the jvm from crashing with an OOM: metaspace because the jvm doesn't give us a chance to close and dereference the underlying classloaders before it crashes. It WILL collect classloaders under normal memory pressure, just not metaspace pressure. To fix this, I check if the MaxMetaspaceSize is set via an MxBean and, if it is, we fill the cache with regular soft references. We are going to change the bash script to not set -XX:MaxMetaspaceSize by default so most builds should probably end up correctly closing the classloaders after this change. But we should break existing builds that set MaxMetaspaceSize but don't crash. As part of this commit, I audited all of the places where we were instantiating ClassLoaderCache instances and instead pass in the state's ClassLoaderCache instance. This reduces the total number of classloaders created. |
||
|---|---|---|
| .. | ||
| main | ||
| test/scala/sbt/internal/inc | ||