java - JPA Hibernate DBCP Tomcat 内存不足

标签 java spring hibernate tomcat jpa

我在新版本的应用程序中每天都会收到 OutOfMemory 错误。我们为 Tomcat 分配了 1.5 GB 的堆。

使用 Eclipse 内存分析器 ( http://www.eclipse.org/mat/ ) 我在最短累积路径下得到了以下内容

org.apache.tomcat.dbcp.pool.impl.CursorableLinkedList$Listable @ 0xa1566cc8  
    _head org.apache.tomcat.dbcp.pool.impl.CursorableLinkedList @ 0xa1566ca8  
      _pool org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool @ 0xa1566c38 
         connectionPool org.apache.tomcat.dbcp.dbcp.BasicDataSource @ 0xa1566980 
             dataSource org.springframework.orm.jpa.JpaTransactionManager @ 0xa0b01760 
                   <Java Local> java.lang.Thread @ 0xa4005900 ajp-8141-5 Thread 

对此的进一步检查显示了很多重复的字符串,它们是 Hibernate 查询。在我的应用程序主屏幕上,我加载了一个文档列表。堆转储中重复查询存在 8,241 次。

我还注意到 org.apache.tomcat.dbcp.dbcp.AbandonedObjectPool 中包含 1 GB 的堆。此文档查询正在加载文档二进制数据。它加载的文档大约为 1MB。这让我怀疑 List 没有被垃圾收集器清理干净。我们将从查询中删除不必要的数据,但我仍然担心对象仍然存在。

我正在使用 JPA、Hibernate 和 Spring。我在获取文档列表的方法上使用 @Transactional(readOnly=true)。这是我的数据源 Spring 配置:

<jee:jndi-lookup jndi-name="jdbc/MyDB" id="myDataSource"/>

    <bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

        <property name="dataSource" ref="myDataSource"/>
        <property name="persistenceUnitName" value="WebPU"/>
        <property name="persistenceProvider">
            <bean class="org.hibernate.ejb.HibernatePersistence" />
        </property>
        <property name="jpaVendorAdapter">
            <bean
                class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="database" value="SQL_SERVER" />
                <property name="showSql" value="false" />
                <property name="generateDdl" value="false" />
            </bean>
        </property>

    </bean>

     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="myEmf" />
    </bean>

我正在使用 Tomcat 来提供连接池。这是我的配置:

<Resource auth="Container" driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" initialSize="20"
  logAbandoned="true" maxActive="100" maxIdle="30" maxWait="10000" name="jdbc/MyDB" password="pass" poolPreparedStatements="true" removeAbandoned="true" removeAbandonedTimeout="30" 
  type="javax.sql.DataSource" 
  url="jdbc:sqlserver://devmssql;databaseName=MY_DEV;responseBuffering=adaptive;port=1444" 
  username="user"/>

服务层有@Transactional。我的 JPA 查询如下所示:

public List<Document> getDocs(int cId, int lId, int ldId) { 
        CriteriaBuilder queryBuilder = getEntityManager().getCriteriaBuilder();
        CriteriaQuery<Document> select = queryBuilder.createQuery(Document.class);

        Root<Document> from = select.from(Document.class);

        select.where(
                queryBuilder.and(queryBuilder.equal(from.get(Document_.cId), cId),
                queryBuilder.equal(from.get(Document_.lId), lId),
                queryBuilder.equal(from.get(Document_.ldId), ldId)));




        TypedQuery<Document> tq = getEntityManager().createQuery(select);

        final List<Document> rl = tq.getResultList();

        return rl;
    }

我应该寻找什么来帮助确定内存泄漏的根本原因?是否有可能导致此问题的 DBCP、Hibernate 或 Spring 设置?您注意到 JPA 查询代码中有什么可能起作用吗?

最佳答案

我强烈建议使用 VisualVMjProfiler以确定泄漏。恕我直言,这是最简单的方法。

关于java - JPA Hibernate DBCP Tomcat 内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10194818/

相关文章:

java - 实体不通过 TomEE 上的 Spring(CrudRepository) 持久化

java - 如何知道使用了哪个框架?

java - 无法使用 Java 获取 XML 标签

java - 忽略 Java Arraylist 中的负值进行计算

java - Spring OAuth2.0 : Where does spring store the access token?

java - 带有应用程序/八位字节流的spring boot multipartFile抛出异常

java - 什么是 Java 中的 IncompatibleClassChangeError 异常?

java - 没有连接表的单向一对多关系

java - 操作链 - 无法选择子菜单

java - 'Ѐ' "new byte[' 中的 Ѐ']"是什么意思?