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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17823599/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 15:08:10  来源:igfitidea点击:

Possible Memory Leak due to org.hibernate.internal.SessionFactoryImpl

javahibernatememory-leaksout-of-memory

提问by pitu_rfr

I have made and MVC webapp in Java, but when I run it, once a day, it turns down again due to a memory error.

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

This error is this: Exception in thread "http-apr-12136-exec-42" java.lang.OutOfMemoryError: Java heap space

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

java.sql.SQLException: java.lang.OutOfMemoryError: Java heap space

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

I have the hprof with the stats of the crash, where specific how is the memory used. If I open the hprof with the Eclipse Memory Analizer, I have this results:

我有带有崩溃统计信息的 hprof,其中具体说明了内存的使用情况。如果我使用 Eclipse Memory Analizer 打开 hprof,我会得到以下结果:

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

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

Or in a folder: https://mega.co.nz/#F!6hJUyKbQ!D_Kb23E3KfAJqcd5EeAt0A

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

In the Overview report, I have this graphic (OverviewEMA.JPG): I don't know what this graphic say... I don't understand it.

在概览报告中,我有这张图 (OverviewEMA.JPG): 我不知道这张图在说什么……我不明白。

In the second tab, the default report, I have this graphic (DefaulReport_EMA.JPG): It say the problem can be one instance of "org.hibernate.internal.SessionFactoryImpl". But I don't know how to solve that instance.

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

In the next tabs. In the dominator tree, again appears the previous instance, which use around 42MB of memory (the same that show the first graphic). The image is DominatorTree_EMA.JPG

在下一个选项卡中。在支配树中,再次出现前一个实例,它使用大约 42MB 的内存(与显示第一个图形相同)。图片是 DominatorTree_EMA.JPG

If I expand the first class (the class that gives problems), I have this graphic (DominatorTreeExpanded_EMA.JPG):

如果我展开第一个类(产生问题的类),我有这个图形(DominatorTreeExpanded_EMA.JPG):

In the next tab, in the histogram, the graphic is this (Histogram_EMA.JPG):

在下一个选项卡中,在直方图中,图形是这样的 (Histogram_EMA.JPG):

And in the Unreachable objects, the result is this (UnreachableObjects_EMA.JPG):

而在 Unreachable 对象中,结果是这样的 (UnreachableObjects_EMA.JPG):

I don't understand very well this 2 last graphics

我不太明白这最后两个图形

At last, I also have the report of Java VisualVM, where I have this results (Heapdump_JVM.JPG):

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

According to this graphic, the HashMap objects are the problem, besides Integer and String objects. The Hashmap objects I think are the objects of the model that the classes send to jsp files, and it proceed from the JPA Objects (the objects of Hibernate), so the problem could be this, but I don't know how to solve it...

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

Could someone help me? Someone know how can I fix it? Do you need some information more?

有人可以帮助我吗?有人知道我该如何修复它?您需要更多信息吗?

Thanks!

谢谢!

采纳答案by Thomas W

On reviewing DominatorTree_Expanded, you appear to be creating SessionFactorys repeatedly (there are 144 in memory). This should be created only once, at startup, then used to create any number of Sessions.

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

See also my comments below about proper use of Hibernate Session.

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



Your Hibernate session should be localto the request -- and closed when the request ends. You can use the "OpenSessionInView" pattern to bind a session to the thread during Controller processing & View (JSP) rendering.

您的 Hibernate 会话应该是请求的本地会话——并在请求结束时关闭。您可以使用“OpenSessionInView”模式在控制器处理和视图 (JSP) 渲染期间将会话绑定到线程。

I suspect, since you are going OutOfMemory, that you are keeping a Hibernate Session as an "instance variable" of your Controller -- or as a static somewhere. This should never be done.

我怀疑,由于您要使用 OutOfMemory,因此您将 Hibernate 会话保持为控制器的“实例变量”——或者作为某个地方的静态变量。永远不应该这样做。

Since web requests may be concurrent, a Controller should never share request-processing state (such as Hibernate Sessions, or mutable variables) as instance variables. This would cause unwanted interaction between separate requests & threads.

由于 Web 请求可能是并发的,因此控制器不应将请求处理状态(例如 Hibernate 会话或可变变量)作为实例变量共享。这会导致单独的请求和线程之间发生不必要的交互。

回答by pitu_rfr

Sorry, I can't write with line spaces, so I write in a new answer.

对不起,我不能用行空格写,所以我写了一个新的答案。

The problem could be the text that I put before in the comment of your answer? I declare the Classes Controller like this.

问题可能是我之前在您的答案的评论中放入的文字?我像这样声明类控制器。

@Controller
public class HelloController {

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

The object that I create many times is that HttpServletRequest and Response? Or is another?

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

I don't know where I create the SessionFactorys.

我不知道在哪里创建 SessionFactory。

The other possible place, could be in the Dao, where I declare an Entity Manager like this in all Dao.

另一个可能的地方,可能是在 Dao 中,我在所有 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;
    }

Some of this could be the problem?

其中一些可能是问题所在?

Thanks again!

再次感谢!

回答by pitu_rfr

Ok. Thanks.

行。谢谢。

And how should I declare the EntityManager??

我应该如何声明 EntityManager ?

I'm reading the link of Hibernate in Springsource, but I don't see nothing extrange in my code. I don't know how I have to do...

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

My applicattionContext.xml is this:

我的 applicationContext.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>

How I have to make the applicationContext.xml? And how I should declare the EntityManager in the classes?

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

Or do you think I should use SessionFactory??

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

Sorry for the inconvenience.

带来不便敬请谅解。