有一个连接到Oracle数据库读取数据的服务,它使用Hibernate-3.6和SpringData-JPA-1.10.x。主机频繁生成堆转储,导致内存不足。
通过使用Eclipse MAT分析了一些堆转储后,发现大多数内存积累在一个org.hibernate.engine.StatefulPersistenceContext -> org.hibernate.util.IdentityMap -> java.util.LinkedHashMap实例中。
The thread java.lang.Thread @ 0x84427e10 ... : 29 keeps local variables with total size 1,582,637,976 (95.04%) bytes.
The memory is accumulated in one instance of "java.util.LinkedHashMap" loaded by "".
在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。这两个类型都应与该接口所处理的领域类(domain class)相一致。
API活动方法带有注释@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)。