Speicherlecks in Java EE-Anwendungen

Es gibt verschiedene Arten von Speicherlecks, z. B. Thread- und ThreadLocal-Lecks, Klassenladerlecks, Systemressourcenlecks und Verbindungslecks. Die Methoden zur Erkennung von Speicherlecks beinhalten in der Regel eine Überprüfung von JVMTI- (Java™ Virtual Machine Tool Interface) oder PMI-Zählern (Performance Monitoring Infrastructure), um eine langsame Zunahme der Java-Heapspeicherbelegung oder der nativen Heapspeicherbelegung zu überwachen.

Anmerkung: WebSphere Application Server Version 8.5 verfügt über eine hierarchisch strukturierte und musterbasierte Erkennung, Verhinderung und Behandlung von Speicherlecks. Hierbei wird eine Überwachung auf verdächtige Muster im Anwendungscode während der Ausführung durchgeführt. WebSphere Application Server verfügt über einige Mittel zum Schutz vor Speicherlecks, wenn Anwendungen gestoppt oder erneut implementiert werden. Wenn die Erkennung, Verhinderung und Behandlung von Speicherlecks aktiviert ist, überwacht WebSphere Application Server die Anwendungs- und Modulaktivität und führt Diagnoseaktionen aus, um Speicherlecks zu erkennen und zu beheben, wenn eine Anwendung oder ein einzelnes Modul stoppt. Diese Funktion hilft bei der Verbesserung der Anwendungsverfügbarkeitszeit bei häufigen erneuten Anwendungsimplementierungen, ohne dass der Server erneut gestartet wird.

Speicherlecks in Klassenladern

Viele Speicherlecks zeigen sich als Klassenladerlecks. Eine Java-Klasse wird durch ihren Namen und den Klassenlader, durch den sie geladen wurde, eindeutig identifiziert. Klassen mit demselben Namen können mehrfach in einer einzelnen JVM geladen werden, jeweils in einem anderen Klassenlader. Jede Webanwendung erhält einen eigenen Klassenlader, sodass WebSphere Application Server Anwendungen eingrenzen kann.

Ein Objekt behält einen Verweis auf die Klasse bei, in der es eine Instanz ist. Eine Klasse behält einen Verweis auf den Klassenlader bei, durch den sie geladen wurde. Der Klassenlader behält einen Verweis auf jede Klasse bei, die er geladen hat. Durch das Beibehalten eines Verweises von einer Webanwendung auf ein einzelnes Objekt wird jede von der Webanwendung geladene Klasse im Speicher belassen. Diese Verweise bleiben häufig nach dem erneuten Laden einer Webanwendung erhalten. Mit jedem erneuten Laden werden mehr Klassen im Speicher belassen, wodurch es zu einem Fehler aufgrund abnormaler Speicherbedingungen kommt.

Speicherlecks in Klassenladern werden normalerweise durch den Anwendungscode oder den JRE-Code verursacht.

Durch JRE ausgelöste Speicherlecks

Speicherlecks treten auf, wenn JRE-Code (JRE - Java Runtime Environment) mit dem Kontextklassenlader ein Anwendungssingleton lädt. Diese Singletons können Threads oder andere Objekte sein, die von JRE mithilfe des Kontextklassenladers geladen werden.

Wenn der Webanwendungscode die Initialisierung eines Singleton oder eines statischen Initialisierungsoperators auslöst, gelten folgende Bedingungen:
  • Der Kontextklassenlader wird zum Webanwendungsklassenlader.
  • Ein Verweis auf den Webanwendungsklassenlader wird erstellt. Für diesen Verweis wird nie eine Garbage-Collection durchgeführt.
  • Der Klassenlader und alle von ihm geladenen Klassen werden im Speicher belassen.

Durch die Anwendung ausgelöste Speicherlecks

Kategorien für Speicherlecks, die durch die Anwendung ausgelöst werden:
  • Angepasste Klasse ThreadLocal
  • Webanwendungsklasseninstanz als ThreadLocal-Wert
  • Indirekt durch einen ThreadLocal-Wert gesperrte Webanwendungsklasseninstanz
  • ThreadLocal-Pseudoleck
  • ContextClassLoader und Threads, die durch Webanwendungen erstellt werden
  • ContextClassLoader und Threads, die durch Klassen erstellt werden, die vom allgemeinen Klassenlader geladen werden
  • Variablen für statische Klassen
  • JDBC-Treiberregistrierung: RMI-Ziele
Weitere Informationen zu Speicherlecks, die durch Anwendungen ausgelöst werden, finden Sie in den Artikeln http://wasdynacache.blogspot.com/2012/01/websphere-classloader-memory-leak.html, http://www.websphereusergroup.org.uk/wug/files/presentations/31/Ian_Partridge_-_WUG_classloader_leaks.pdf und http://www.ibm.com/support/docview.wss?uid=swg1PM39870.

WebSphere Application Server verfügt jetzt über einige Mittel zum Schutz vor Speicherlecks, wenn Anwendungen gestoppt oder erneut implementiert werden. WebSphere Application Server überwacht die Anwendungs- und Modulaktivität und führt Diagnoseaktionen aus, wenn eine Anwendung oder ein einzelnes Modul gestoppt wird.

Diese Speicherleckfunktion in WebSphere Application Server besteht aus drei Teilen: Erkennung, Verhinderung und Behandlung.
  1. Erkennung: Warnungen ausgeben, wenn ein Speicherleck festgestellt wird. Durch eine Kombination von Standard-API-Aufrufen und einigen Reflexionstricks, wenn eine Webanwendung gestoppt, deimplementiert oder erneut geladen wird. WebSphere Application Server sucht nach bekannten Ursachen von Speicherlecks und gibt Warnungen aus, wenn ein Speicherleck festgestellt wird:
    [11/17/11 12:01:05:911 EST] 00000005 LeakDetection E   CWMML0015E: Die Webanwendung [WasSwat#WasSwatWeb.war] hat einen ThreadLocal mit einem Schlüssel des Typs [test.memleak.MyThreadLocal] (Wert [test.memleak.MyThreadLocal@216c691]) und dem Wertetyp [test.memleak.MyCounter] (Wert [test.memleak.MyCounter@21942ff]) erstellt, konnte diesen aber nicht entfernen, als sie gestoppt wurde. 
  2. Die Verhinderung ist standardmäßig aktiviert und betrifft nur durch JRE ausgelöste Speicherlecks. Durch JRE ausgelöste Speicherlecks werden durch die Initialisierung von Singletons während des Serverstarts vermieden, wenn der Klassenlader des Anwendungsservers der Kontextklassenlader ist.
  3. Behandlung: Führen Sie proaktive Schritte zur Behebung von Speicherlecks aus. Diese Maßnahmen haben angemessene Standardwerte und werden fallorientiert konfiguriert.
    protected void com.ibm.ws.classloader.clearReferences(){
            if(ENABLE_CLEAR_REFERENCES_JDBC)
    				clearReferencesJdbc();
    		if(ENABLE_CLEAR_REFERENCES_THREADS)
            				clearReferencesThreads();
            if(ENABLE_CLEAR_REFERENCES_THREADLOCALS)
    				clearReferencesThreadLocals();
    		if(ENABLE_CLEAR_REFERENCES_RMI_TARGETS)
            				clearReferencesRmiTargets();
            if(ENABLE_CLEAR_REFERENCES_STATICS)
                clearReferencesStaticFinal();
    }
Tabelle 1. Speicherleckbehebung - Zusammenfassungsmatrix
Ursache des Speicherlecks Korrekturmaßnahmen Eigenschaften von WebSphere Application Server Java Virtual Machine für die Aktivierung und Steuerung
Threadlocal Erneuern Sie Threads im Thread-Pool über einen konfigurierbaren Zeitraum. Das Abrufen von Threads aus dem Pool ermöglicht die Durchführung einer Garbage-Collection für die Threads und Threadlocals.
  • com.ibm.ws.runtime.component.MemoryLeakConfig.clearReferencesThreadLocal
  • com.ibm.ws.runtime.component.MemoryLeakConfig.renewThreadPoolNames
  • com.ibm.ws.runtime.component.MemoryLeakConfig.threadPoolRenewalDelayFactor
  • com.ibm.ws.util.ThreadPool.DEFAULT_THREAD_RENEWAL_DELAY
HTTP-Client-Keepalive-Threads Wechseln Sie den Thread zum übergeordneten Klassenlader.
  • com.ibm.ws.runtime.component.MemoryLeakConfig.clearReferencesHttpClientKeepAliveThread
Zeitgeberthreads Verwenden Sie Reflexion, um alle neuen Tasks zu stoppen, die möglicherweise geplant sind.
  • com.ibm.ws.runtime.component.MemoryLeakConfig.clearReferencesStopTimerThreads
Nicht JVM-gesteuerte Threads Wenn der Thread über ein Steuerprogramm gestartet wird, beenden Sie das Steuerprogramm oder unterbrechen Sie den Thread.
  • com.ibm.ws.runtime.component.MemoryLeakConfig.clearReferencesInterruptThreads
JDBC-Treiber Heben Sie die Registrierung aller JDBC-Treiber auf, die von der Webanwendung registriert wurden und die die Webanwendung übergangen hat.
  • com.ibm.ws.runtime.component.MemoryLeakConfig.preventJreMemoryLeak
Ressourcenpaket Löschen Sie alle Pakete aus dem Ressourcenpaketcache (ResourceBundle), die von diesem Klassenlader oder einem beliebigen anderen Klassenlader, dem dieses Ladeprogramm übergeordnet ist, geladen wurden.
  • com.ibm.ws.runtime.component.MemoryLeakConfig.preventJreMemoryLeak
RMI-Ziele Löschen Sie die Werte in sun.rmi.transport.ObjectTable.implTable und sun.rmi.transport.ObjectTable.objTable mithilfe von Reflexion.
  • com.ibm.ws.runtime.component.MemoryLeakConfig.preventJreMemoryLeak
Variablen für statische Klassen WebSphere Application Server setzt den Wert aller Variablen für statische Klassen der Klassen, die vom Anwendungs- oder Modulklassenlader geladen werden, auf einen Leerwert.
  • com.ibm.ws.runtime.component.MemoryLeakConfig.clearReferencesStatic com.ibm.ws.runtime.component.MemoryLeakConfig.filterPrefixes

Symbol, das den Typ des Artikels anzeigt. Konzeptartikel



Symbol für Zeitmarke Letzte Aktualisierung: 25.05.2016
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=ctrb_memleakdetection
Dateiname:ctrb_memleakdetection.html