This is a bug in ColdFusion that can cause memory leaks when using a
to load external jar files. Thus, this can cause memory leaks in
and any other system that uses this technology. However there is a
workaround for the issue.
To explain the problem, first we need to look at some key issues with a
URLClassLoader. URLClassLoaders are notorious for causing memory leaks,
because, for them to be garbage collected, all instances to themselves
and the classes that they have created
need to be garbage collectible.
This means that if you access a class from a URLClassLoader and hold it
somewhere in memory, then the URLClassLoader can
never be garbage collected.
This is exactly what happens with ColdFusion.
When ColdFusion does some introspection and resolution of ColdFusion code
against a Java object, somewhere, deep inside its hidden internals, it keeps a
strong reference to the Class object that refers to that Java object. This
means that when the JVM comes along to garbage collect the instance of the
URLClassLoader, it can't do it, because ColdFusion has a reference to a class
that it loaded somewhere inside.
So, the memory leak only ever actually happens when an instance of a
URLClassLoader is no longer available to ColdFusion, as it is never then garbage
collected by the JVM.
How does this translate to using JavaLoader? Well, a perfect example of this is
where you put an instance of JavaLoader in the application scope, because
generally it is used as a singleton. JavaLoader (and anything that
subsequently uses JavaLoader) has an instance of a URLClassLoader inside
it. However, when the application scope times out, the JavaLoader CFC may
well be garbage collected, but the URLClassLoader isn't, which can cause a
To note however, in production systems the leak is minimised in situations like
this, as it is often very rare that the application scope will ever time out.
So what is the workaround for this issue? To note, I have been pushing at Adobe
to get a hotfix out for CFMX to resolve this issue, but we can definitely still
use this technique now, without having to worry about memory leaks.
Essentially, the memory leak only happens when the URLClassLoader is no longer
available to CF, i.e. an application scope times out, or something similar – so
we just need to make sure that it never, ever, times out. How can we do
that? why, put it in the Server scope of
Since variables in the Server scope never time out, we don't need to worry about
the URLClassLoader (or JavaLoader) being lost and then recreated, as it always
exists. As long as you put it in the Server scope under a key no one will
ever need to utilise (I like a hard coded UUID myself)! Hence we beat the
memory leak monster!
I have just committed a fix for Transfer that automatically puts the JavaLoader
it uses into the Server scope, so even if your TransferFactory times out, the
JavaLoader never will, which means there is no leak, and the RC2 for 0.6.3 will
have this as well.
Hopefully Adobe will put out a hotfix for this issue, but until then, put your
JavaLoaders in the Server scope.