对 hibernate session impl 的线程本地引用,导致 session impl 不被垃圾收集
我正在使用本地线程来管理我的休眠会话。最近,我在生产服务器上看到了 OutOfMemory 异常。我在 heap_dump 上运行 Eclipse MAT,发现我的很多会话没有被垃圾收集,即使它们由于被 tomcatse ThreadWithAttributes 对象引用而被关闭。现在这让我发疯,我在不同的论坛上看到了很多有类似问题的帖子,但没有答案。任何帮助将不胜感激。
谢谢
I am using thread local to manage my hibernate sessions. Recently I have been seeing OutOfMemory exceptions on my production server. I ran Eclipse MAT on the heap_dump and saw a lot of my sessions are not getting garbage collected even though they are being closed due to them being referenced by tomcatse ThreadWithAttributes object. This is driving me crazy right now I have seen a lot of posts with similar questions on different forums but no answers. Any assistance will be greatly appreciated.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您在 Web 应用程序中使用 Hibernate Session,请不要让 ThreadLocal 中的 Session 对象跨请求保留在那里 - 因为无论如何您都无法控制线程,它们属于容器。
如果您需要在 Web 请求的生命周期内创建和关闭 Session,并且您不想在任何地方传递 Session 对象,那么您应该考虑编写 ServletFilter 来处理清理工作 - 它将在每个请求周围被调用。您还可以让该过滤器提交或回滚您可能已启动的任何事务。
您应该阅读此页面以了解如何执行此操作的简单秘诀:http://community.jboss.org /wiki/OpenSessioninView
If your are using Hibernate Sessions in a web application, DON'T let the Session objects in ThreadLocal stay there across requests - since you have no control over the threads anyway, they belong to the container.
If you need to create and close a Session for the lifetime of a web request, and you don't want to pass the Session object around everywhere, you should consider writing a ServletFilter to handle the cleanup - it will get invoked around every request. You could also let that filter commit or rollback any transactions you may have started.
You should read this page for a simple recipe to how to do it: http://community.jboss.org/wiki/OpenSessioninView
感谢您的回复。我目前正在视图中使用打开的会话,使用 getCurrentSession() 这意味着会话是根据请求进行的,并在 transaction.commit() 上关闭。我可以看到会话正在关闭(尽管没有被清零),但 ThreadWithAttributes tomcat 类以某种方式保存对 sessionImpl 的引用,防止它被垃圾收集。每个线程都会发生这种情况。我的数据库非常大,因此这会在几个小时或最多一天后导致内存不足错误,并且服务器需要退回。
thanks for your reply. I am currently using open session in view, using getCurrentSession() which means that the session is per request cand closes on transaction.commit(). I can see that the sessions are being closed (though not nulled out) yet somehow the ThreadWithAttributes tomcat class hold a reference to the sessionImpl preventing it from being garbage collected. This happens with every thread. My database is pretty large so this cause out of memory errors after a few hours or a day at most and the server needs to be bounced.