2009-05-29 10 views
5

Nous avons récemment commencé à utiliser Hibernate et nous nous habituons toujours à la façon dont cela fonctionne. L'une des choses que nous avons vu est que même après que toutes les sessions sont fermées et que les références sont hors de portée, Hibernate semble toujours maintenir les valeurs de base de données précédemment utilisées dans son cache.Comment forcer hibernate à libérer de la mémoire une fois la session fermée?

Nous avons du code qui lit à partir d'un ensemble de tables en plusieurs passes. Parce que toute la mémoire est libérée très parcimonieusement, les passes ultérieures ralentissent jusqu'à un crawl.

Existe-t-il un moyen de forcer Hibernate à effacer son cache?

Un appel explicite à System.gc() n'aide pas. (Oui, je sais que c'est une suggestion)

Informations supplémentaires: Nous avons explicitement désactivé le cache de second niveau.

+3

Je suppose que vous n'êtes pas en utilisant le cache de second niveau de mise en veille prolongée alors? Quelle stratégie utilisez-vous pour la gestion de session? "Session par thread"? –

+0

Nous utilisons session par thread, et nous avons explicitement désactivé le cache de second niveau – StudioEvoque

Répondre

10

Vous pouvez essayer d'appeler Session.clear pour forcer l'effacement du cache de premier niveau. Veillez à appeler Session.flush en premier pour écrire les modifications en attente dans la base de données. Si cela "corrige" le problème, alors je soupçonne que quelque chose contient toujours une référence à la session, empêchant les objets du cache d'être récupérés. Vous devrez peut-être obtenir un vidage de tas de votre programme pour localiser la fuite.

+0

Il "fixé" le problème :) Comme vous l'avez suggéré, nous examinons certains de nos "HibernateUtils" créés pour voir où nous restez sur des références de session. – StudioEvoque

+0

Vous pouvez également envisager d'utiliser un framework tel que Spring pour gérer vos sessions et transactions Hibernate si vous ne l'avez pas déjà fait. –

+0

Merci, cette suggestion m'a aidé à résoudre un problème qui a tué mon application Java pour les derniers jours! – mahonya

2

Hibernate dispose également d'un cache de second niveau optionnel qui pourrait être en jeu. Je suis d'accord avec Rob, le moyen le plus simple de le savoir est de voir ce qui reste en mémoire après la fin de la session.

Mon outil préféré actuel pour ceci est YourKit qui est commercial et pas exactement bon marché. Ils offraient (et peuvent encore offrir) une option de licence personnelle très peu coûteuse (99 IIRC). J'ai utilisé YourKit précisément pour cette tâche lors du dépannage des problèmes d'utilisation du tas avec Alfresco ECM. Il existe d'autres outils disponibles (par exemple CodeGear JGears) qui, à mon avis, fonctionnent très bien.

Vous pouvez envisager d'utiliser un produit en mode d'évaluation - si cela trouve votre problème, il pourrait gagner sa subsistance;)

+0

Si explict GC n'aide pas, les objets doivent toujours être référencés quelque part dans votre code. Un profileur avec la détection de fuite de mémoire est le chemin le plus rapide vers une réponse à mon humble avis puisque vous * verrez * le chemin causant la fuite. Bonne chance! –

Questions connexes