2011-06-20 10 views
10

Zastanawiam się, czy iw jaki sposób powinienem zająć się komponentami MBeans, które są zarejestrowane bezpośrednio lub pośrednio z mojej aplikacji, która zostanie wdrożona na kontenerze serwletów.JMX: Jak zapobiegać wyciekom pamięci Classloader w kontenerze serwletów?

W większości przypadków istnieją dwie możliwości, aby pobrać MBeanServer, które można wykorzystać do rejestracji

  • tworzyć własne MBeanServer użyciu MBeanServerFactory.createMBeanServer()

  • Korzystając ManagementFactory.getPlatformMBeanServer()

Podczas korzystania pierwsza opcja, łatwo wyrejestrować wszystkie MBeans: Jus t wywołaj MBeanServer.releaseMBeanServer(myMBeanServer).

Ale co z drugą opcją używaną często w wielu aplikacjach innych firm? (i BTW, jest to również zalecana metoda od firmy Sun/Oracle).

Ponieważ używana jest platforma MBeanServer, nie zostanie wyrejestrowana, gdy kontekst serwletu zostanie zniszczony - ale jeszcze gorzej nadal będzie zawierał odwołanie do programu ładującego klasy aplikacji WWW.
W konsekwencji wszystkie statyczne odwołania aplikacji internetowej nie zostaną zwolnione, co spowoduje wyciek.

Jeśli chcesz przetestować to: wystarczy wdrożyć prostą aplikację sieci Web, która przydziela tablicę 100 MB, która jest statycznie powiązana i która używa sterownika jdbc Oracle (zarejestruje komponent MBean diagnostyki przy użyciu serwera platformy MBS), wdrożony na kocur. Zatrzymaj aplikację i uruchom ją ponownie - powtórz to, a trafisz na numer OutOfMemoryError.

Pytania:

  • Czy muszę radzić sobie z tymi problemami w ogóle czy jest to problem z kontenera serwletów i/lub 3rd biblioteki strona?

  • Czy istnieje sposób na pobranie wszystkich MBeans z MBeanServer, które klasy są ładowane przez konkretną ClassLoader?

  • Co mogę zrobić, aby temu zapobiec? Czy muszę śledzić wszystkie zarejestrowane MBeans na platformie MBeanServer i wyrejestrować ją podczas contextDestroyed()?

+0

Może rzucić okiem na http://stackoverflow.com/questions/386892/is-it-necessary-to-unregister-an-mbean-from-the-platform-mbean-server – nfechner

Odpowiedz

1

Co mogę zrobić, aby temu zapobiec? Czy I musi śledzić wszystkie zarejestrowane MBeans do platformy MBeanServer i wyrejestrować ją podczas contextDestroyed()?

To była moja standardowa rada. Nie znam lepszej opcji.

0

Co mówi bkail. Ponadto, jeśli korzystasz z frameworka takiego jak Spring (zobacz MBeanExporter), powinieneś zadbać o wyrejestrowanie obiektów JMX po zamknięciu kontekstu, co powinno nastąpić w ramach ponownego wdrażania aplikacji webapp.

3

Używam takich złych stron trzecich. Aby zapewnić właściwe zamknięcie kontekstu serwletu, wyliczam fasole za pomocą mbeanServer.queryMBeans(null, null), a następnie unregisterMBean() ziaren znajdujących się w domenie podmiotów trzecich.

Set<ObjectInstance> beans = mbeanServer.queryMBeans(null, null); 
for (ObjectInstance objectInstance : beans) { 
    if (objectInstance.getObjectName().getDomain().equals("third-party-domain")) { 
     try { 
      mbeanServer.unregisterMBean(objectInstance.getObjectName()); 
     } catch (MBeanRegistrationException exception) { 
      //error handling 
     } catch (InstanceNotFoundException exception) { 
      //error handling 
     } 
    } 
} 
+0

ja również wyrejestrowuje tylko komponenty MBeans załadowane przez moduł ładujący aplikacji WWW: 'if (mbeanServer.getClassLoaderFor (objectInstance.getObjectName() == Thread.currentThread(). getContextClassLoader())' – John29

Powiązane problemy