Search code examples
jakarta-eeejbwildflyclassloader

Are static fields normally unloaded on undeployment in WildFly?


I am using WildFly 11 Final, and created the following EJB:

@Singleton
@Startup
public class MyDebug {
    private static final MyStaticSingleton myStaticSingleton = new MyStaticSingleton();
}

Now, if I redeploy the Application and look into the Heap via JVisualVm, I will see one more Instance of MyStaticSingleton for every redeployment. The instances of MyStaticSingleton are referenced by different ClassLoaders.

Is it normal behavoir that the ClassLoader of a JavaEE Application does not get discarded after the undeployment of an Application?


Solution

  • Most probably you have a leak, caused by some misbehaviour of your application. That's quite a common problem in fact.

    The main issue is not an incremented number of instances of your singleton, but rather an incremented number of classloaders and therefore number of loaded classes (which could be finally huge). You can easily prove that with javacore dumps.

    To solve that, you have to find an object preventing each of these classloaders from discarding, and so all the loaded classes.

    One well-known example of such misbehaviour of EE application is using log4j with enabled shutdown hooks (enabled by default).

    UPDATE

    Just to confirm, statically referenced object in given example could not cause mentioned classloaders / native memory leak. Moreover, since the static field declared final - it conforms EJB specification.

    As it was mentioned by TS, the main suspect is connection pool, which violates EJB specification by running it's own threads.

    Using threading in EE environment, especially along with context classloaders, is a typical reason of such leaks.