JMX:如何防止servlet容器中的Classloader内存泄漏?

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()

Bre*_*ail 1

我可以做什么来防止这种情况发生?我是否必须跟踪所有注册到平台 MBeanServer 的 MBean 并在 contextDestroyed() 期间取消注册它?

这是我的标准建议。我不知道有更好的选择。