JBoss EAP 6.4.5与Hibernate 4.2.21内存占用异常求助
排查SessionFactoryImpl内存泄漏的思路分享
我之前维护基于JBoss EAP 6.x和Hibernate 4.2.x的老项目时,碰到过类似但细节不同的内存泄漏问题,给你整理几个实用的排查和解决方向:
先揪出重复创建SessionFactory的根源
SessionFactory设计上应该是单例实例,一下子出现1112个实例肯定是代码里存在重复创建的逻辑。你可以检查:- 是不是在每次请求、组件初始化时都调用了
new Configuration().buildSessionFactory()这类代码? - 有没有在JBoss的模块化部署中,每个WAR/EAR模块都单独打包了Hibernate依赖,导致类加载器隔离,每个模块都创建了自己的SessionFactory?
- 是不是在每次请求、组件初始化时都调用了
定位空类加载器与ConcurrentHashMap引用的关联
空类加载器通常意味着类加载器已被GC回收,但实例还被外部引用持有。这里的引用来自java.util.concurrent.ConcurrentHashMap$Node[],你需要:- 用MAT(Memory Analyzer Tool)的「Path to GC Roots」功能,找到这个ConcurrentHashMap的归属——是Hibernate内部的缓存容器,还是你业务代码里的静态集合?
- 如果是业务代码里的静态Map,检查是否存在只存不取、未在组件销毁时清理引用的情况。
结合Hibernate 4.2.x的已知问题调整排查方向
你提到的那个Hibernate issue是EntityManagerFactory的泄漏问题,和你的SessionFactory场景有差异,但可以延伸排查:- 确认所有SessionFactory实例在生命周期结束时都调用了
close()方法?比如应用停止、组件销毁时,有没有正确释放SessionFactory资源? - 查看Hibernate 4.2.21的修复日志,有没有和SessionFactory缓存、类加载器引用相关的未修复bug?
- 确认所有SessionFactory实例在生命周期结束时都调用了
利用JBoss的类加载特性优化部署
JBoss EAP 6.x的模块化类加载容易导致类隔离问题:- 建议把Hibernate相关jar包部署到JBoss的
modules目录作为全局模块,让所有应用共享同一个类加载器下的Hibernate,避免因类重复加载产生多个SessionFactory实例。 - 检查应用的
jboss-deployment-structure.xml配置,有没有错误的类加载隔离规则导致Hibernate类被重复加载。
- 建议把Hibernate相关jar包部署到JBoss的
借助工具追踪创建栈
用JProfiler或VisualVM这类工具,跟踪SessionFactoryImpl的创建调用栈,就能精准定位到重复创建的代码位置,这比盲猜高效得多。
如果能拿到MAT分析的引用链详情,或者SessionFactory的创建栈信息,还能进一步缩小问题范围。
内容的提问来源于stack exchange,提问作者Kacu
相关产品推荐
相关产品推荐

