73 votes

Pourquoi java.lang.ref.Finalizer consomme-t-il autant de mémoire ?

J'ai lancé un vidage de tas sur mon programme. Quand je l'ai ouvert dans l'outil d'analyse de la mémoire, j'ai trouvé que le java.lang.ref.Finalizer para org.logicalcobwebs.proxool.ProxyStatement prenait beaucoup de mémoire. Pourquoi est-ce le cas ?

screenshot

76voto

Peter Lawrey Points 229686

Certaines classes implémentent la fonction Object.finalize() méthode. Les objets qui surchargent cette méthode doivent être appelés par un finalisateur d'appel de thread en arrière-plan, et ils ne peuvent pas être nettoyés avant que cela ne se produise. Si ces tâches sont courtes et que vous n'en éliminez pas beaucoup, tout fonctionne bien. Cependant, si vous créez beaucoup de ces objets et/ou que leurs finaliseurs prennent beaucoup de 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 d'objets finalize()d si vous le pouvez (si vous écrivez la classe pour l'objet)
  • faire un finalize très court (si vous devez l'utiliser)
  • ne pas jeter ces objets à chaque fois (essayer de les réutiliser)

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

11voto

Stephen C Points 255558

D'après ce que je peux voir, Proxool est un pool de connexion pour les connexions JDBC. Cela me suggère que le problème est que votre application utilise mal le pool de connexion. Au lieu d'appeler close sur les objets de déclaration, votre code les abandonne probablement et/ou leurs connexions parentes. Le Proxool s'appuie sur des finaliseurs pour fermer les objets sous-jacents implémentés par le pilote ... mais cela nécessite ces instances de Finalizer. Cela pourrait également signifier que vous faites en sorte que la connexion ouvre/ferme 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 dans votre code s'il y a des objets ResultSet, Statement et/ou Connection qui fuient, et de vous assurer que vous les fermez en finally blocs.


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 retenue par l'objet Finalizer dont l'id est 2aab07855e38 . Si vous avez toujours le fichier de vidage, jetez un oeil à ce que que Finalizer fait référence. Il semble plus problématique que les objets Proxool.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X