web-dev-qa-db-fra.com

est une fuite de mémoire? pourquoi Java.lang.ref.Finalizer mange autant de mémoire

J'ai exécuté un vidage de tas sur mon programme. Lorsque je l'ai ouvert dans l'outil d'analyseur de mémoire, j'ai constaté que le Java.lang.ref.Finalizer pour org.logicalcobwebs.proxool.ProxyStatement prenait beaucoup de mémoire. Pourquoi cela est-il ainsi?

screenshot

59
fuyou001

Certaines classes implémentent la méthode Object.finalize(). Les objets qui remplacent cette méthode doivent être appelés par un finaliseur d'appel de thread d'arrière-plan, et ils ne peuvent pas être nettoyés jusqu'à ce que cela se produise. Si ces tâches sont courtes et que vous n'en jetez pas beaucoup, tout fonctionne bien. Cependant, si vous créez beaucoup de ces objets et/ou leurs finalisateurs prennent du temps, la file d'attente des objets à finaliser s'accumule. Il est possible que cette file d'attente utilise toute la mémoire.

La solution est

  • n'utilisez pas les objets finalize () d si vous le pouvez (si vous écrivez la classe pour l'objet)
  • faire finaliser très court (si vous devez l'utiliser)
  • ne jetez pas ces objets à chaque fois (essayez de les réutiliser)

La dernière option est probablement la meilleure pour vous lorsque vous utilisez une bibliothèque existante.

63
Peter Lawrey

D'après ce que je peux comprendre, Proxool est un pool de connexions pour les connexions JDBC. Cela me suggère que le problème est que votre application utilise abusivement le pool de connexions. Au lieu d'appeler close sur les objets de l'instruction, votre code les supprime probablement et/ou leurs connexions parentes. Le Proxool s'appuie sur les finaliseurs pour fermer les objets sous-jacents mis en œuvre par le pilote ... mais cela nécessite ces instances de Finalizer. Cela peut également signifier que vous provoquez la connexion pour ouvrir/fermer des connexions de base de données (réelles) plus fréquemment que nécessaire, ce qui serait mauvais pour les performances.

Je vous suggère donc de vérifier votre code pour les objets ResultSet, Statement et/ou Connection perdus, et assurez-vous de les fermer dans les blocs finally.


En regardant le vidage de la mémoire, je suppose que vous vous demandez où vont les 898 527 228 octets. La grande majorité est conservée par l'objet Finalizer dont l'ID est 2aab07855e38. Si vous avez toujours le fichier de vidage, regardez à quoi queFinalizer fait référence. Il semble plus problématique que les objets Proxool.

9
Stephen C