Мне интересно, следует ли и как мне иметь дело с MBeans, которые зарегистрированы прямо или косвенно из моего приложения, которое развертывается в контейнере сервлетов.
В большинстве случаев есть два варианта получения MBeanServer, которые вы можете использовать для регистрации.
создайте свой собственный
MBeanServerс помощьюMBeanServerFactory.createMBeanServer()Используйте
ManagementFactory.getPlatformMBeanServer()
При использовании первого варианта легко отменить регистрацию всех компонентов MBean: просто вызовите MBeanServer.releaseMBeanServer(myMBeanServer).
А как насчет второго варианта, который часто используется во многих сторонних приложениях? (и, кстати, это также рекомендуемый путь от Sun/Oracle).
Поскольку используется платформа MBeanServer, ее регистрация не будет отменена при уничтожении контекста сервлета, но, что еще хуже, она по-прежнему содержит ссылку на загрузчик классов веб-приложения.
Как следствие, все статические ссылки веб-приложения не будет выпущен, что приведет к утечке.
Если вы хотите проверить это: просто разверните простое веб-приложение, которое выделяет массив 100 МБ, на который ссылаются статически и который использует драйвер oracle jdbc (он зарегистрирует диагностический MBean с помощью сервера mbean платформы), развернутый на tomcat. Остановите приложение и перезапустите его — повторите это, и вы нажмете OutOfMemoryError.
Вопросы:
Должен ли я иметь дело с этими проблемами в целом или это проблема контейнера сервлетов и/или сторонней библиотеки?
Есть ли способ получить все MBeans
MBeanServer, классы которых загружаются определеннымClassLoader?Что я могу сделать, чтобы предотвратить это? Должен ли я отслеживать все зарегистрированные компоненты MBean на платформе
MBeanServerи отменять их регистрацию в течениеcontextDestroyed()?