Java JPA EntityManager大内存问题
我在使用Spring、Hibernate和JPA的web应用程序时遇到了一些问题。问题是内存消耗非常高,随着时间的推移而增加,而且似乎从未减少。它们很可能源于对EntityManager的错误使用。我到处找了找,但还没有找到确切的东西 我们使用的DAO都扩展了以下GenericDAO,其中注入了我们唯一的EntityManager:Java JPA EntityManager大内存问题,java,spring,hibernate,jpa,entitymanager,Java,Spring,Hibernate,Jpa,Entitymanager,我在使用Spring、Hibernate和JPA的web应用程序时遇到了一些问题。问题是内存消耗非常高,随着时间的推移而增加,而且似乎从未减少。它们很可能源于对EntityManager的错误使用。我到处找了找,但还没有找到确切的东西 我们使用的DAO都扩展了以下GenericDAO,其中注入了我们唯一的EntityManager: public abstract class GenericDAOImpl<E extends AbstractEntity<P>, P> i
public abstract class GenericDAOImpl<E extends AbstractEntity<P>, P> implements
GenericDAO<E, P> {
@PersistenceContext
@Autowired
private EntityManager entityManager;
[...]
这可能是因为实体管理器未被清除?我倾向于同意您的评估。刷新EntityManager不会从内存中清除任何内容,它只会将实体与数据库同步 可能发生的情况是EntityManager保留对持久性上下文中所有对象的引用,而您永远不会关闭上下文。(有一个类似的问题。)清除它确实会删除EntityManager对实体的所有引用,但是,如果您发现自己经常需要调用clear(),您可能应该重新评估如何使用EntityManager。如果您只是想避免LaZyPrimalI化异常,请考虑Spring *中的OpenSSeVIEWVIEW筛选器。这允许您在惰性地加载实体的同时仍然让Spring管理bean的生命周期。bean的生命周期管理是Spring框架的一大优势,因此您需要确保覆盖该行为是您真正想要的 确实有些情况下,您需要一个长寿命的EntityManager,但这些情况相对较少,需要大量的理解才能正确地实现 *注意:OpenSessionInView需要非常小心以避免出现错误。这是一个如此大的问题。小心使用 编辑
此外,您也不需要使用
@Autowired
注释@PersistenceContext
元素。@PersistenceContext
本身进行连接。您应该从上面的私有EntityManager EntityManager中删除@Autowired
注释
并从上下文定义文件中删除entityManager
bean定义。此外,如果不使用
和
XML标记,则必须在上下文中定义PersistenceAnnotationBeanPostProcessor
bean。对于不符合JEE的应用程序服务器,不应使用@Autowired/@PersistenceContext private EntityManager EntityManager代码>
你应该这样做:
class SomeClass {
@PersistenceUnit private EntityManagerFactory emf;
public void myMethod() {
EntityManager em = null;
try {
em = emf.createEntityManager();
// do work with em
}
} catch (SomeExceptions e) {
// do rollbacks, logs, whatever if needed
} finally {
if (em != null && em.isOpen()) {
// close this sucker
em.clear();
em.close();
}
}
}
一些注意事项:
- 这适用于带有Spring+Hibernate的非完整JEE应用服务器
- 我已经用JDK1.7和1.8对它进行了测试,在泄漏方面没有区别
- 常规的ApacheTomcat不是真正的JEE应用服务器(然而)
我在使用PersistenceContext
时遇到了与spring
和hibernate
相同的问题。你解决漏洞了吗?定期运行em.clear()正是我的处理速度大幅提高的原因
One instance of "org.hibernate.impl.SessionFactoryImpl" loaded by "org.apache.catalina.loader.WebappClassLoader @ 0xc3217298" occupies 15,256,880 (20.57%) bytes. The memory is accumulated in one instance of "org.hibernate.impl.SessionFactoryImpl" loaded by "org.apache.catalina.loader.WebappClassLoader @ 0xc3217298".
class SomeClass {
@PersistenceUnit private EntityManagerFactory emf;
public void myMethod() {
EntityManager em = null;
try {
em = emf.createEntityManager();
// do work with em
}
} catch (SomeExceptions e) {
// do rollbacks, logs, whatever if needed
} finally {
if (em != null && em.isOpen()) {
// close this sucker
em.clear();
em.close();
}
}
}