org.hibernate.internal.SessionFactoryImpl可能导致内存泄漏

时间:2013-07-24 01:13:14

标签: java hibernate memory-leaks out-of-memory

我已经用Java创建了MVC webapp,但是当我每天运行一次时,由于内存错误它会再次关闭。

这个错误是这样的: 线程“http-apr-12136-exec-42”中的异常java.lang.OutOfMemoryError:Java堆空间

java.sql.SQLException:java.lang.OutOfMemoryError:Java堆空间

我有hprof与崩溃的统计数据,具体如何使用内存。如果我使用Eclipse Memory Analizer打开hprof,我会得到以下结果:

在rar:https://mega.co.nz/#!Ht41xJDJ!MooePBSv5yOYSNN5OuvF7Afn2rcN-KJ2tXGSsgqtsaI

或在文件夹中:https://mega.co.nz/#F!6hJUyKbQ!D_Kb23E3KfAJqcd5EeAt0A

在概述报告中,我有这个图形(OverviewEMA.JPG): 我不知道这张图片说的是什么......我不明白。

在第二个标签中,默认报告,我有这个图形(DefaulReport_EMA.JPG): 它说问题可能是“org.hibernate.internal.SessionFactoryImpl”的一个实例。但我不知道如何解决这个问题。

在下一个标签中。在统治者树中,再次出现前一个实例,它使用大约42MB的内存(显示第一个图形的相同)。图像是DominatorTree_EMA.JPG

如果我扩展第一个类(提供问题的类),我有这个图形(DominatorTreeExpanded_EMA.JPG):

在下一个标签中,在直方图中,图形为此(Histogram_EMA.JPG):

在Unreachable对象中,结果就是这个(UnreachableObjects_EMA.JPG):

我不太了解这最后一张图片

最后,我还有Java VisualVM的报告,我有这个结果(Heapdump_JVM.JPG):

根据此图,除了Integer和String对象之外,HashMap对象也是问题所在。我认为Hashmap对象是类发送给jsp文件的模型的对象,它从JPA Objects(Hibernate的对象)开始,所以问题可能是这个,但我不知道如何解决它...

有人可以帮助我吗?有人知道我该怎么办呢?您还需要更多信息吗?

谢谢!

3 个答案:

答案 0 :(得分:4)

在查看DominatorTree_Expanded时,您似乎重复创建了SessionFactorys(内存中有144个)。这应该只在启动时创建一次,然后用于创建任意数量的Sessions。

另请参阅下面有关正确使用Hibernate Session的评论。


您的Hibernate会话应该本地到请求 - 并在请求结束时关闭。您可以使用" OpenSessionInView"在Controller处理期间将会话绑定到线程的模式&查看(JSP)渲染。

我怀疑,因为你要OutOfMemory,你将Hibernate Session作为"实例变量"您的控制器 - 或作为静态某处。永远不应该这样做。

由于Web请求可能是并发的,因此Controller永远不应将请求处理状态(例如Hibernate Sessions或可变变量)作为实例变量共享。这将导致不同请求之间的不必要的交互。线程。

答案 1 :(得分:1)

抱歉,我不能用行空格写,所以我写了一个新答案。

问题可能是我之前在你的答案评论中提出的文字?我像这样声明Classes Controller。

@Controller
public class HelloController {

    @RequestMapping(value="/hello.htm")
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

我多次创建的对象是HttpServletRequest和Response?或者是另一个?

我不知道在哪里创建SessionFactorys。

另一个可能的地方,可能是在道,我在所有Dao中宣布这样的实体经理。

@Repository(value = "contratoDao")
public class JPAContratoDao implements ContratoDao {

    private EntityManager em = null;

    /*
     * Sets the entity manager.
     */
    @PersistenceContext
    public void setEntityManager(EntityManager em) {
        this.em = em;
    }

其中一些可能是问题?

再次感谢!

答案 2 :(得分:1)

确定。感谢。

我应该如何声明EntityManager?

我正在阅读Springource中的Hibernate链接,但我的代码中没有看到任何异常。我不知道我该怎么做......

我的applicattionContext.xml是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <!-- holding properties for database connectivity /-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- enabling annotation driven configuration /-->
    <context:annotation-config/>

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
      <property name="driverClassName" value="${jdbc.driverClassName}"/>
      <property name="url" value="${jdbc.url}"/>
      <property name="username"  value="${jdbc.username}"/>
      <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
            p:dataSource-ref="dataSource"
            p:jpaVendorAdapter-ref="jpaAdapter">
            <property name="loadTimeWeaver">
              <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
            </property>                             
            <property name="persistenceUnitName" value="springappPU"></property>
    </bean>

    <bean id="jpaAdapter"
            class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
            p:database="${jpa.database}"
            p:showSql="${jpa.showSql}"/>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
            p:entityManagerFactory-ref="entityManagerFactory"/>

    <tx:annotation-driven transaction-manager="transactionManager"/>


    <!-- Scans the classpath of this application for @Components to deploy as beans -->
    <context:component-scan base-package="com.companyname.springapp.repository" />
    <context:component-scan base-package="com.companyname.springapp.service" />

</beans>

我如何制作applicationContext.xml?我应该如何在类中声明EntityManager?

或者您认为我应该使用SessionFactory吗?

很抱歉给您带来不便。