Mysql
 sql >> Base de données >  >> RDS >> Mysql

Fuite de mémoire Java MySQL JDBC

J'ai eu exactement le même problème. J'avais besoin de garder 1 connexion active pour 3 threads et en même temps chaque thread devait exécuter beaucoup d'instructions (de l'ordre de 100k). J'ai été très prudent et j'ai fermé chaque instruction et chaque jeu de résultats en utilisant un algorithme try....finally.... De cette façon, même si le code échouait d'une manière ou d'une autre, l'instruction et le jeu de résultats étaient toujours fermés. Après avoir exécuté le code pendant 8 heures, j'ai été surpris de constater que la mémoire nécessaire est passée des 35 Mo initiaux à 500 Mo. J'ai généré un dump de la mémoire et je l'ai analysé avec Mat Analyzer d'Eclipse. Il s'est avéré qu'un objet com.mysql.jdbc.JDBC4Connection prenait 445 Mo de mémoire en gardant en vie certains objets openStatements qui, à leur tour, maintenaient en vie environ 135 000 entrées de hashmap, probablement de tous les résultats. Il semble donc que même si vous fermez toutes vos instructions et tous vos ensembles de résultats, si vous ne fermez pas la connexion, elle conserve des références à celles-ci et le GarbageCollector ne peut pas libérer les ressources.

Ma solution  :après une longue recherche, j'ai trouvé cette déclaration des gars de MySQL :

"Un test rapide consiste à ajouter "dontTrackOpenResources=true " à votre URL JDBC. Si la fuite de mémoire disparaît, un chemin de code dans votre application ne ferme pas les instructions et les ensembles de résultats."

Voici le lien :http://bugs.mysql.com/bug.php? id=5022 . Alors j'ai essayé ça et devinez quoi? Après 8 heures, j'avais besoin d'environ 40 Mo de mémoire pour les mêmes opérations de base de données. Peut-être qu'un pool de connexions serait souhaitable, mais si ce n'est pas une option, c'est la meilleure chose que j'ai trouvée.