sql >> Base de Datos >  >> RDS >> Mysql

Fuga de memoria Java MySQL JDBC

Tuve exactamente el mismo problema. Necesitaba mantener 1 conexión activa para 3 subprocesos y, al mismo tiempo, cada subproceso tenía que ejecutar muchas declaraciones (del orden de 100k). Fui muy cuidadoso y cerré cada declaración y cada conjunto de resultados usando un intento... finalmente... algoritmo. De esta manera, incluso si el código fallaba de alguna manera, la declaración y el conjunto de resultados siempre estaban cerrados. Después de ejecutar el código durante 8 horas, me sorprendió descubrir que la memoria necesaria pasó de los 35 MB iniciales a 500 MB. Generé un volcado de la memoria y lo analicé con Mat Analyzer de Eclipse. Resultó que un objeto com.mysql.jdbc.JDBC4Connection estaba tomando 445 MB de memoria para mantener activos algunos objetos openStatements que, a su vez, mantenían activos alrededor de 135 000 entradas de hashmap, probablemente de todos los conjuntos de resultados. Entonces parece que incluso si cierra todas sus declaraciones y conjuntos de resultados, si no cierra la conexión, mantiene las referencias a ellos y GarbageCollector no puede liberar los recursos.

Mi solución :después de una larga búsqueda encontré esta declaración de los chicos de MySQL:

"Una prueba rápida es agregar "dontTrackOpenResources=true " a su URL de JDBC. Si la fuga de memoria desaparece, alguna ruta de código en su aplicación no está cerrando declaraciones y conjuntos de resultados".

Aquí está el enlace:http://bugs.mysql.com/bug.php? id=5022 . Así que probé eso y ¿adivinen qué? Después de 8 horas, necesitaba alrededor de 40 MB de memoria para las mismas operaciones de la base de datos. Tal vez sería aconsejable un grupo de conexiones, pero si esa no es una opción, esta es la siguiente mejor opción que encontré.