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