问题
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.
This error is this: Exception in thread "http-apr-12136-exec-42" java.lang.OutOfMemoryError: Java heap space
java.sql.SQLException: java.lang.OutOfMemoryError: Java heap space
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:
In rar: https://mega.co.nz/#!Ht41xJDJ!MooePBSv5yOYSNN5OuvF7Afn2rcN-KJ2tXGSsgqtsaI
Or in a folder: 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.
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.
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
If I expand the first class (the class that gives problems), I have this graphic (DominatorTreeExpanded_EMA.JPG):
In the next tab, in the histogram, the graphic is this (Histogram_EMA.JPG):
And in the Unreachable objects, the result is this (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):
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...
Could someone help me? Someone know how can I fix it? Do you need some information more?
Thanks!
回答1:
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.
See also my comments below about proper use of Hibernate Session.
Your Hibernate session should be local to 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.
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.
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.
回答2:
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?
I don't know where I create the SessionFactorys.
The other possible place, could be in the Dao, where I declare an Entity Manager like this in all 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!
回答3:
Ok. Thanks.
And how should I declare the 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...
My applicattionContext.xml is this:
<?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?
Or do you think I should use SessionFactory??
Sorry for the inconvenience.
来源:https://stackoverflow.com/questions/17823599/possible-memory-leak-due-to-org-hibernate-internal-sessionfactoryimpl