Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA EntityManager大内存问题_Java_Spring_Hibernate_Jpa_Entitymanager - Fatal编程技术网

Java JPA 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

我在使用Spring、Hibernate和JPA的web应用程序时遇到了一些问题。问题是内存消耗非常高,随着时间的推移而增加,而且似乎从未减少。它们很可能源于对EntityManager的错误使用。我到处找了找,但还没有找到确切的东西

我们使用的DAO都扩展了以下GenericDAO,其中注入了我们唯一的EntityManager:

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();
      }
   }
}