Ich erhalte täglich OutOfMemory-Fehler in einer neuen Version meiner Anwendung. Wir haben 1,5 GB Heap für Tomcat reserviert.
Mit dem Eclipse Memory Analyzer ( Ссылка ) habe ich Folgendes unter dem kürzesten Akkumulationspfad
erhalten %Vor%Eine weitere Überprüfung zeigt viele doppelte Strings, bei denen es sich um Hibernate-Abfragen handelt. Auf dem Startbildschirm meiner Anwendung lade ich eine Liste von Dokumenten. Ein Duplikat der Abfrage existiert 8.241 mal im Heap-Dump.
Ich habe auch bemerkt, dass 1 GB des Heaps in org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool enthalten ist. Diese Dokumentabfrage hat die Binärdaten des Dokuments geladen. Das Dokument, das geladen wird, ist ungefähr 1 MB. Das lässt mich vermuten, dass die Liste vom Müllsammler nicht aufgeräumt wird. Wir werden unnötige Daten aus der Abfrage entfernen, aber es betrifft mich immer noch, dass Objekte herumstehen.
Ich verwende JPA, Hibernate und Spring. Ich verwende @Transactional(readOnly=true)
für die Methode, die die Dokumentenliste abruft. Hier ist meine Spring-Konfiguration für die Datenquelle:
Ich verwende Tomcat, um das Verbindungspooling bereitzustellen. Hier ist meine Konfiguration:
%Vor%Die Serviceebene hat die @Transactional. Meine JPA-Abfrage sieht folgendermaßen aus:
%Vor%Was soll ich suchen, um die Ursache des Speicherlecks zu identifizieren? Gibt es Einstellungen für DBCP, Hibernate oder Spring, die dazu beitragen könnten? Gibt es irgendetwas, das Sie im JPA-Abfragecode bemerken, der dazu beitragen könnte?
Versuchen Sie, den EntityManager-Cache zu löschen, bevor Sie von der Methode zurückkehren. Rufen Sie zuerst EntityManager.flush () und dann clean () auf. Dies kann hilfreich sein, wenn Ihr EntityManager lange "lebt" und von vielen Datenbankoperationen verwendet wird.
Wenn Sie Spring verwenden, können Sie den Einsatz von Hibernate für problematische Situationen aufgeben und mit JDBC arbeiten. Spring bietet JDBCTemplate, um problemlos mit Abfragen arbeiten zu können, und bietet außerdem eine allgemeine Transaktionsverwaltungsschnittstelle, sodass Sie Hibernate-Operationen mit JDBC-Abfragen mischen können.