On Tue, Nov 8, 2016 at 3:27 AM, Daniel Weber <
daniel.w...@gmail.com> wrote:
> Thanks a lot! This fixed our problem :-)
Good to hear.
There is test coverage demonstrating lack of leaks for basic
scenarios, which seems to have included yours, but there can always be
some surprises waiting in the wings. I found that when you have some
method defined outside the build, say in a plugin:
package some.permanent.pkg;
public class SomeClass {
@Whitelisted // go ahead, use me without worries
public static String checkTheFrobnitz(Object whatever) {…}
}
and you call it from Pipeline script with an argument whose *runtime
type* is defined in that script:
import some.permanent.pkg.*
stage('Checks') {
echo "Frobnitz verified: ${SomeClass.checkTheFrobnitz(this)}"
}
then Groovy will helpfully cache the fact that
`SomeClass.checkTheFrobnitz` on (this version of) `WorkflowScript`
should resolve to `checkTheFrobnitz(Object)` rather than some other
overload or weird dynamic invocation. And it will hold onto this cache
from `SomeClass`—so a new cache entry is created on every build, whose
“retained set” includes every class that build defined. The cache uses
a soft reference, so the entry will *eventually* get tossed out, but
not promptly after the end of the build (the VM argument
`-XX:SoftRefLRUPolicyMSPerMB=1` seems to ameliorate the problem). I
have not yet figured out a way to efficiently search for these entries
and blow them away, so for now I just hope this case is rare in
practice.
To make things more interesting, Groovy 1.x (used in Jenkins 1.x) and
2.x (used in Jenkins 2.x) each have their own set of bugs in this
area. The Java platform is not innocent either; there are poorly
conceived caches baked into JavaBeans and Serialization which do not
get cleared on time without some tortuous workarounds. Pipeline
implementation code tries to clean up everything it can—enough to make
the defined tests pass. Stay vigilant and report any reproducible
leaks in the future: classes not unloaded, `GroovyClassLoader`
instances never being collected.
/me sighs