Description
Actual Situation
The class MemoryAllocationExports creates a memory leak caused by AllocationCountingNotificationListener that is added but never removed, when this libary is included within a WAR application that gets deployed on a Tomcat server.
The AllocationCountingNotificationListener is added to the class GarbageCollectorMXBean (see class GarbageCollectorExtIml at the attached screenshot) that is loaded by java.lang.ClassLoader, which is different from the org.apache.catalina.loader.ParallelWebappClassLoader.
public MemoryAllocationExports() {
AllocationCountingNotificationListener listener = new AllocationCountingNotificationListener(allocatedCounter);
for (GarbageCollectorMXBean garbageCollectorMXBean : getGarbageCollectorMXBeans()) {
if (garbageCollectorMXBean instanceof NotificationEmitter) {
((NotificationEmitter) garbageCollectorMXBean).addNotificationListener(listener, null, null);
}
}
}
Because of this the AllocationCountingNotificationListener has a reference to a class with a different classloader, which prevents that this class gets collected by garbage collector.
Possible solution (outlook)
At the moment the class MemoryAllocationExports provides no function to retrieve a instance of AllocationCountingNotificationListener, which is needed to call NotificationEmitter#removeNotificationListener:
for (GarbageCollectorMXBean garbageCollectorMXBean : getGarbageCollectorMXBeans()) {
if (garbageCollectorMXBean instanceof NotificationEmitter) {
((NotificationEmitter) garbageCollectorMXBean).removeNotificationListener(listener);
}
}
When the above code gets called the class is collected and clean up by the garbage collector.
The class DefaultExports contains already a function for initialization. Possibly this class would also be suitable to provide a corresponding function for the clean shutdown, which could be called during ServletContextListener#contextDestroyed.
Environment
- Server: Apache Tomcat 9.0.65
- JVM: 17.0.4.1+1 Eclipse Adoptium
- OS: Linux 4.19.0-13-amd64
- Simpleclient Version: 0.16.0