【发布时间】:2018-11-22 04:04:09
【问题描述】:
有一个服务连接到 Oracle DB 以读取数据,它使用 Hibernate-3.6 和 SpringData-JPA-1.10.x。堆转储频繁生成,导致主机内存不足。
在使用 Eclipse MAT 分析几个 heapdump 后,发现大部分内存是在 org.hibernate.engine.StatefulPersistenceContext -> org.hibernate.util.IdentityMap -> java.util.LinkedHashMap 的一个实例中积累的。
线程 java.lang.Thread @ 0x84427e10 ... : 29 保持本地 总大小为 1,582,637,976 (95.04%) 字节的变量。
内存在“java.util.LinkedHashMap”的一个实例中累积 由“”加载。
在 StackOverflow 上搜索它,它说 SessionFactory 应该是单例的,并且 session.flush() 和 session.clear() 应该在每次调用之前调用以清除缓存。但是 SessionFactory 并没有在代码中显式初始化或使用。
是什么导致了这里的内存泄漏(看起来每个查询的结果都被缓存而不是清除)以及如何解决它?
有关 Spring Data 配置的更多信息:
TransactionManager 初始化为:
<tx:annotation-driven mode='proxy' proxy-target-class='true' />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
....
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" depends-on="...">
....
</bean>
为了与表交互,声明一个接口扩展 Spring Data Repository 和 JpaSpecificationExecutor。两者都输入到它将处理的域类中。
API 活动方法有注解@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)。
【问题讨论】:
-
发布您的休眠配置以及您的初始化方式
SessionFactory。 -
同时打开调试日志并发布该日志。
-
@Amogh 正如问题中提到的,由于我们使用的是 Hibernate 和 Spring Data JPA,因此 SessionFactory 没有显式初始化或在代码中使用。
标签: java hibernate memory-leaks spring-data-jpa sessionfactory