Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Java-MySQL-JDBC-Speicherleck

Ich hatte genau das gleiche Problem. Ich musste eine Verbindung für 3 Threads aktiv halten und gleichzeitig musste jeder Thread viele Anweisungen ausführen (in der Größenordnung von 100.000). Ich war sehr vorsichtig und schloss jede Anweisung und jede Ergebnismenge mit einem try....finally...-Algorithmus. Auf diese Weise wurden die Anweisung und die Ergebnismenge immer geschlossen, selbst wenn der Code auf irgendeine Weise fehlschlug. Nachdem ich den Code 8 Stunden lang ausgeführt hatte, stellte ich überrascht fest, dass der erforderliche Speicher von den anfänglichen 35 MB auf 500 MB angestiegen war. Ich habe einen Dump des Speichers erstellt und ihn mit Mat Analyzer von Eclipse analysiert. Es stellte sich heraus, dass ein com.mysql.jdbc.JDBC4Connection-Objekt 445 MB Speicher beanspruchte, um einige openStatements-Objekte am Leben zu erhalten, die wiederum etwa 135.000 Hashmap-Einträge am Leben hielten, wahrscheinlich aus allen Ergebnismengen. Es scheint also, dass selbst wenn Sie alle Ihre Anweisungen und Resultsets schließen, wenn Sie die Verbindung nicht schließen, Verweise auf sie beibehalten werden und der GarbageCollector die Ressourcen nicht freigeben kann.

Meine Lösung :nach langer Suche fand ich diese Aussage von den Jungs bei MySQL:

„Ein schneller Test ist das Hinzufügen von „dontTrackOpenResources=true " zu Ihrer JDBC-URL. Wenn das Speicherleck verschwindet, schließt ein Codepfad in Ihrer Anwendung keine Anweisungen und Ergebnismengen."

Hier ist der Link:http://bugs.mysql.com/bug.php? id=5022 . Also habe ich das versucht und weißt du was? Nach 8 Stunden waren ungefähr 40 MB Arbeitsspeicher für die gleichen Datenbankoperationen erforderlich. Vielleicht wäre ein Verbindungspool ratsam, aber wenn das keine Option ist, ist dies das nächstbeste, was ich gefunden habe.