我已经用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的对象)开始,所以问题可能是这个,但我不知道如何解决它...
有人可以帮助我吗?有人知道我该怎么办呢?您还需要更多信息吗?
谢谢!
答案 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吗?
很抱歉给您带来不便。