I am wondering if or how I should deal with MBeans which are registered directly or indirectly from my application which gets deployed on a servlet container.
In most cases there are two options to retrieve a MBeanServer
which you can use for registering
create your own
MBeanServer
usingMBeanServerFactory.createMBeanServer()
Use
ManagementFactory.getPlatformMBeanServer()
When using the first option, it's easy to deregister all MBeans:
Just invoke MBeanServer.releaseMBeanServer(myMBeanServer)
.
But what about the second option which is used often in many 3rd party applications? (and BTW, this is also the recommended way from Sun/Oracle).
Because the platform MBeanServer
is used, it won't be deregistered when the servlet context is destroyed - but even worse it still helds a reference to the web application classloader.
As a consequence all static references of the web application won't get released which results in a leak.
If you like to test this: Just deploy a simple web application which allocates a 100MB array which is references statically and which uses an oracle jdbc driver (it will register a diagnostic MBean using the platform mbean server), deployed on tomcat. Stop the application and restart it - repeat this, and you'll hit an OutOfMemoryError
.
Questions:
Do I have to deal with these issues in general or is it a problem of the servlet container and/or the 3rd party library?
Is there a way to get all MBeans of an
MBeanServer
which classes are loaded by a specificClassLoader
?What can I do to prevent this? Do I have to keep track of all registered MBeans to the platform
MBeanServer
and unregister it duringcontextDestroyed()
?