openrewrite / rewrite-gradle-plugin

OpenRewrite's Gradle plugin.
Apache License 2.0
65 stars 40 forks source link

RewriteClassLoader is never freed, effectively a memory leak #132

Closed sambsnyd closed 1 year ago

sambsnyd commented 2 years ago

When multiple builds are run in the same Gradle daemon if the rewrite classpath changes we'll create a new RewriteClassLoader, but the old one and all the classes it ever loaded never get garbage collected.

We load JGit within RewriteClassLoader to keep it isolated from the rest of the plugin classpath. But JGit registers a shutdown hook in a static initializer. So that holds a reference to the classloader until the end of the JVM.

This becomes a problem only when you do multiple builds on the same Gradle daemon with different classpaths.

image

This shutdown hook is registered in a static initializer in org.eclipse.jgit.util.FS: image

We can't load this class from the parent classloader because it's shaded into rewrite-core. To fix this we have to do something like:

sambsnyd commented 2 years ago

This is the branch I was working off of, whenever I come back to try and fix this for real: https://github.com/openrewrite/rewrite-gradle-plugin/tree/classloader-memory-leak