在大多数情况下,有两种方法可以检索可用于注册的MBeanServer
>使用MBeanServerFactory.createMBeanServer()创建自己的MBeanServer
>使用ManagementFactory.getPlatformMBeanServer()
当使用第一个选项时,很容易注销所有MBean:
只需调用MBeanServer.releaseMBeanServer(myMBeanServer).
但是在第三方应用程序中常常使用的第二个选项呢?
(和BTW,这也是Sun / Oracle推荐的方法).
因为使用了平台MBeanServer,所以当servlet上下文被破坏时,它不会被注销,但是更糟糕的是,它仍然保留对Web应用程序类加载器的引用.因此,Web应用程序的所有静态引用将不会被释放导致泄漏.
如果你想测试这个:只需部署一个简单的web应用程序,它分配一个100MB的数组,这个数组是静态引用的,它使用了一个oracle jdbc驱动程序(它将使用平台mbean服务器注册一个诊断MBean),部署在tomcat上.停止应用程序并重新启动它 – 重复此操作,并且您将打一个OutOfMemoryError.
问题:
>我一般要处理这些问题,还是servlet容器和/或第三方库的问题?
>有没有办法获得MBeanServer的所有MBean,哪些类由特定的ClassLoader加载?
>我可以做些什么来防止这种情况?我必须跟踪所有注册的MBean到平台MBeanServer并在contextDestroyed()中取消注册?
解决方法
What can I do to prevent this? Do I
have to keep track of all registered
MBeans to the platform MBeanServer and
unregister it during
contextDestroyed()?
这是我的标准建议.我不知道更好的选择.