MRa*_*ser 10 java memory-leaks jmx servlets classloader
我想知道是否或如何处理直接或间接从我的应用程序注册的MBean,该应用程序部署在servlet容器上.
在大多数情况下,有两个选项可用于检索MBeanServer
可用于注册的选项
创建自己的MBeanServer
使用MBeanServerFactory.createMBeanServer()
使用 ManagementFactory.getPlatformMBeanServer()
使用第一个选项时,可以轻松取消注册所有MBean:只需调用即可MBeanServer.releaseMBeanServer(myMBeanServer)
.
但是,在许多第三方应用程序中经常使用的第二个选项呢?(顺便说一句,这也是Sun/Oracle的推荐方式).
因为使用了平台MBeanServer
,所以当servlet上下文被销毁时它不会被注销 - 但更糟糕的是它仍然保留了对web应用程序类加载器的引用.
因此,Web应用程序的所有静态引用都不会被释放,从而导致泄漏.
如果您想测试一下:只需部署一个简单的Web应用程序,该应用程序分配一个100MB阵列,该阵列是静态引用,并使用oracle jdbc驱动程序(它将使用平台mbean服务器注册诊断MBean),部署在tomcat上.停止应用程序并重新启动它 - 重复此操作,然后你就可以了OutOfMemoryError
.
问题:
我是否必须处理这些问题,或者是servlet容器和/或第三方库的问题?
有没有办法获取MBeanServer
特定类加载哪些类的所有MBean ClassLoader
?
我该怎么做才能防止这种情况发生?我是否必须跟踪平台的所有已注册MBean并在MBeanServer
此期间取消注册contextDestroyed()
?
我可以做什么来防止这种情况发生?我是否必须跟踪所有注册到平台 MBeanServer 的 MBean 并在 contextDestroyed() 期间取消注册它?
这是我的标准建议。我不知道有更好的选择。