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