Code Bye

OutOfMemoryError: PermGen space的问题

apache-tomcat-7.0.54经常报OutOfMemoryError: PermGen space错误,根据网上的方法
TOMCAT_HOME/bin/catalina.bat,
在“echo “Using CATALINA_BASE: $CATALINA_BASE””上面加入以下行:
JAVA_OPTS=”-server -Xms800m -Xmx800m    -XX:MaxNewSize=256m”
没用,还是经常报上述错误,下面是两个截图

下面是spring的配置文件:

<?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:aop="http://www.springframework.org/schema/aop"
	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/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

	<bean
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<value>classpath:jdbc.properties</value>
		</property>
	</bean>

	<!-- 定义数据源Bean,使用C3P0数据源实现 -->
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<!-- 设置连接数据库的驱动、URL、用户名、密码 -->
		<property name="driverClass" value="${jdbc.driverClassName}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<!-- 连接池初始时的连接数 -->
		<property name="initialPoolSize" value="1" />
		<property name="minPoolSize" value="1" />
		<!-- 连接池的最大数 -->
		<property name="maxPoolSize" value="40" />
		<!-- 连接的最大空闲时间,如果超过60秒这个时间,某个数据库连接还没有被使用,则会断开掉这个连接 -->
		<property name="maxIdleTime" value="60" />
		<property name="unreturnedConnectionTimeout" value="100" />
		<property name="debugUnreturnedConnectionStackTraces" value="true" />
	</bean>

	<!-- 定义Hibernate的SessionFactory,依赖注入数据源dataSource -->
	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<!-- mappingResouces属性用来列出全部映射文件 -->
		<property name="mappingResources">
			<list>
				<!-- 加载Hibernate映射文件 -->
				<value>com/ntp/model/Admin.hbm.xml</value>
				<value>com/ntp/model/Course.hbm.xml</value>
				<value>com/ntp/model/Coursetype.hbm.xml</value>
				<value>com/ntp/model/CourseUser.hbm.xml</value>
				<value>com/ntp/model/Courseware.hbm.xml</value>
				<value>com/ntp/model/Exercise.hbm.xml</value>
				<value>com/ntp/model/ExerciseUser.hbm.xml</value>
				<value>com/ntp/model/Forum.hbm.xml</value>
				<value>com/ntp/model/ForumUser.hbm.xml</value>
				<value>com/ntp/model/Notice.hbm.xml</value>
				<value>com/ntp/model/Score.hbm.xml</value>
				<value>com/ntp/model/Task.hbm.xml</value>
				<value>com/ntp/model/User.hbm.xml</value>
				<value>com/ntp/model/Video.hbm.xml</value>
			</list>
		</property>
		<!-- 定义Hibernate的SessionFactory的属性 -->
		<property name="hibernateProperties">
			<!-- 指定数据库方言、是否自动建表是否生成SQL语句等 -->
			<value>
				hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
				hibernate.hbm2ddl.auto=update
				hibernate.show_sql=true
				hibernate.format_sql=true
			</value>
		</property>
	</bean>

	<!-- 为继承HibernateDaoSupport的DAO实现类注入SessionFactory -->
	<bean id="adminDao" class="com.ntp.dao.impl.AdminDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="courseDao" class="com.ntp.dao.impl.CourseDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="coursetypeDao" class="com.ntp.dao.impl.CoursetypeDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="courseUserDao" class="com.ntp.dao.impl.CourseUserDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="coursewareDao" class="com.ntp.dao.impl.CoursewareDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="exerciseDao" class="com.ntp.dao.impl.ExerciseDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="exerciseUserDao" class="com.ntp.dao.impl.ExerciseUserDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="forumDao" class="com.ntp.dao.impl.ForumDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="forumUserDao" class="com.ntp.dao.impl.ForumUserDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="noticeDao" class="com.ntp.dao.impl.NoticeDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="scoreDao" class="com.ntp.dao.impl.ScoreDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="taskDao" class="com.ntp.dao.impl.TaskDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="userDao" class="com.ntp.dao.impl.UserDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>
	<bean id="videoDao" class="com.ntp.dao.impl.VideoDaoImpl"
		p:sessionFactory-ref="sessionFactory">
	</bean>

	<!-- 定义业务逻辑组件模板 -->
	<!-- 为之注入DAO组件 -->
	<bean id="daoTemplate" abstract="true" lazy-init="true"
		p:adminDao-ref="adminDao" p:courseDao-ref="courseDao"
		p:coursetypeDao-ref="coursetypeDao" p:courseUserDao-ref="courseUserDao"
		p:coursewareDao-ref="coursewareDao" p:exerciseDao-ref="exerciseDao"
		p:exerciseUserDao-ref="exerciseUserDao" p:forumDao-ref="forumDao"
		p:forumUserDao-ref="forumUserDao" p:noticeDao-ref="noticeDao"
		p:scoreDao-ref="scoreDao" p:taskDao-ref="taskDao" p:userDao-ref="userDao"
		p:videoDao-ref="videoDao">
	</bean>

	<!-- 定义业务逻辑组件,继承业务逻辑组件的模板 -->
	<bean id="adminService" class="com.ntp.service.impl.AdminServiceImpl"
		parent="daoTemplate" />
	<bean id="studentService" class="com.ntp.service.impl.StudentServiceImpl"
		parent="daoTemplate" />
	<bean id="teacherService" class="com.ntp.service.impl.TeacherServiceImpl"
		parent="daoTemplate" />

	<!-- 配置Hibernate的局部事务管理器,需要依赖注入SessionFactory的引用 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
	    p:sessionFactory-ref="sessionFactory">
	</bean>
	<!-- 配置事务增强处理Bean,指定事务管理器 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
	    <tx:attributes>
	        <!-- 所有以""get""开头的方法是read-only的 -->
	        <tx:method name="get*" read-only="true"/>
	        <tx:method name="add*" propagation="REQUIRED"/>
			<tx:method name="update*" propagation="REQUIRED"/>
			<tx:method name="delete*" propagation="REQUIRED"/>
	        <!-- 其他方法使用默认的事务设置 -->
	        <tx:method name="*"/>
	    </tx:attributes>
	</tx:advice>
    <aop:config>
        <!-- 匹配adminService,studentService,teacherService三个Bean所有方法的执行 -->
        <aop:pointcut id="pointcut" expression="bean(adminService)||bean(studentService)||bean(teacherService)"/>
        <!-- 指定在pointcut切入点应用txAdvice事务增强处理 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    </aop:config> 
</beans>
使用过的连接能关闭尽量要关闭,如果有必要进行一下垃圾回收!不过大多数的原因都是忘记关闭数据库连接
引用 1 楼 yushihai 的回复:

使用过的连接能关闭尽量要关闭,如果有必要进行一下垃圾回收!不过大多数的原因都是忘记关闭数据库连接

看不出,这个用c3p0我应该不需要管吧?

sessionFactory 配置的问题
如果是使用eclipse或MyEclipse的话,在tomcat使用的jdk下配置就可以了!
OutOfMemoryError: PermGen space 应该加大内存的PermSize吧,应该增加如下配置:
-XX:PermSize=256m
http://www.cnblogs.com/xwdreamer/archive/2011/11/21/2296930.html 请参考
引用 6 楼 xiaoxiao_shenle 的回复:

http://www.cnblogs.com/xwdreamer/archive/2011/11/21/2296930.html 请参考

引用 5 楼 huangan0301 的回复:

OutOfMemoryError: PermGen space 应该加大内存的PermSize吧,应该增加如下配置:
-XX:PermSize=256m

这个看过,我改成JAVA_OPTS=”-server -XX:PermSize=700M -XX:MaxPermSize=700m 了,还是不行

引用 3 楼 ch656409110 的回复:

sessionFactory 配置的问题

什么问题?


10分
JAVA 永久代溢出了。
楼主设置的参数是堆内存的大小。   永久代是这个。-XX:PermSize=256m
而且这个问题的关键是只是内存不够 调大点即可,还是有内存在不停地泄露?
要是内存泄露,那调大永久代大小只能延缓报错的时间,不能从根本上解决问题的。 可能要通过分析DUMP来找出哪里有问题了。
引用 9 楼 a12939026 的回复:

JAVA 永久代溢出了。
楼主设置的参数是堆内存的大小。   永久代是这个。-XX:PermSize=256m
而且这个问题的关键是只是内存不够 调大点即可,还是有内存在不停地泄露?
要是内存泄露,那调大永久代大小只能延缓报错的时间,不能从根本上解决问题的。 可能要通过分析DUMP来找出哪里有问题了。

我觉得是内存不断泄露,猜测是数据库连接那块,用memoryAnalyzer分析的,看不出来
SEVERE: The web application [/NetworkTeachPlatform] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.
八月 24, 2014 4:16:51 下午 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: The web application [/NetworkTeachPlatform] appears to have started a thread named [MySQL Statement Cancellation Timer] but has failed to stop it. This is very likely to create a memory leak.

引用 9 楼 a12939026 的回复:

JAVA 永久代溢出了。
楼主设置的参数是堆内存的大小。   永久代是这个。-XX:PermSize=256m
而且这个问题的关键是只是内存不够 调大点即可,还是有内存在不停地泄露?
要是内存泄露,那调大永久代大小只能延缓报错的时间,不能从根本上解决问题的。 可能要通过分析DUMP来找出哪里有问题了。

你看下spring配置

如果你不管改多大的值,仍然运行一段时间就out of memory,那几乎可以肯定是内存泄漏

out of memory的时候tomcat应该会生成heapdump和java core,找到这两个文件,用专门的工具看你的代码里面哪些类有内存泄漏的嫌疑

工具方面有很多,IBM的HeaAnalyze是一款不错的内存调优/泄漏检测的工具,同样优秀的还有JRorket

用jconsole或者jvisualvm连上你的应用看看哪里问题,可能是链接没关闭吧
引用 12 楼 qingyuan18 的回复:

如果你不管改多大的值,仍然运行一段时间就out of memory,那几乎可以肯定是内存泄漏

out of memory的时候tomcat应该会生成heapdump和java core,找到这两个文件,用专门的工具看你的代码里面哪些类有内存泄漏的嫌疑

工具方面有很多,IBM的HeaAnalyze是一款不错的内存调优/泄漏检测的工具,同样优秀的还有JRorket

引用 13 楼 fengspg 的回复:

用jconsole或者jvisualvm连上你的应用看看哪里问题,可能是链接没关闭吧

用了看不出来,就是c3p0连接数据库,线程比较多,我上传的图片和spring配置能不能看出来?

肯定是某段代码占用内存过多,根本不是什么数据库连接的问题。还是好好查一下运行哪个功能会使内存增张很快吧。
引用 15 楼 yys79 的回复:

肯定是某段代码占用内存过多,根本不是什么数据库连接的问题。还是好好查一下运行哪个功能会使内存增张很快吧。

某段代码?我用的是HibernateTemplate操作数据库的,业务逻辑很简单,增删改查,

你项目里是不是写了定时器啊
引用 17 楼 wjwkj491 的回复:

你项目里是不是写了定时器啊

没用定时器

把配置文件先注释下看看还报错不。
不报就是代码问题,还报就是配置问题
引用 11 楼 yanxing2012 的回复:
Quote: 引用 9 楼 a12939026 的回复:

JAVA 永久代溢出了。
楼主设置的参数是堆内存的大小。   永久代是这个。-XX:PermSize=256m
而且这个问题的关键是只是内存不够 调大点即可,还是有内存在不停地泄露?
要是内存泄露,那调大永久代大小只能延缓报错的时间,不能从根本上解决问题的。 可能要通过分析DUMP来找出哪里有问题了。

你看下spring配置

这么复杂的问题,光看配置文件,恐怕没几个人答得上。。
permgen space 是JAVA存放class和一些常量的地方,这个问题多数是因为类动态加载导致存放的类过多,最终溢出了。
你需要找到是哪个类过多。 推荐一个文章。
http://java.chinaitlab.com/JDK/793557.html


20分
补充一点,自己的开发环境的话,尽量避免热部署,频繁的热部署,很容易导致OutOfMemoryError: PermGen space
尽量做到修改文件,停掉服务器,然后重启

20分
1、如果你是在Eclipse中运行,应该修改Eclipse里面启动tomcat的参数,而不是修改在“echo “Using CATALINA_BASE: $CATALINA_BASE””上面加入以下行。这样添加只有单独启动tomcat的时候有作用。
 Eclipse VM  arg eg:
-Dcatalina.base=”E:\TMS\apache-tomcat-7.0.52″ -Dcatalina.home=”E:\TMS\apache-tomcat-7.0.52″ -Dwtp.deploy=”E:\TMS\apache-tomcat-7.0.52\webapps” -Djava.endorsed.dirs=”E:\TMS\apache-tomcat-7.0.52\endorsed” -XX:PermSize=64m -XX:MaxPermSize=256m

2、OutOfMemoryError: PermGen space :出现这个的原因是 tomcat的类加载太多,应该和数据库连接之间没有太大的关系。
    
3、出现这个原因 楼主可以用 jconsole 或者jvisualvm 来查看到底是哪儿出问题了。

引用 21 楼 magi1201 的回复:

补充一点,自己的开发环境的话,尽量避免热部署,频繁的热部署,很容易导致OutOfMemoryError: PermGen space
尽量做到修改文件,停掉服务器,然后重启

引用 22 楼 PHIILL_01 的回复:

1、如果你是在Eclipse中运行,应该修改Eclipse里面启动tomcat的参数,而不是修改在“echo “Using CATALINA_BASE: $CATALINA_BASE””上面加入以下行。这样添加只有单独启动tomcat的时候有作用。
 Eclipse VM  arg eg:
-Dcatalina.base=”E:\TMS\apache-tomcat-7.0.52″ -Dcatalina.home=”E:\TMS\apache-tomcat-7.0.52″ -Dwtp.deploy=”E:\TMS\apache-tomcat-7.0.52\webapps” -Djava.endorsed.dirs=”E:\TMS\apache-tomcat-7.0.52\endorsed” -XX:PermSize=64m -XX:MaxPermSize=256m

2、OutOfMemoryError: PermGen space :出现这个的原因是 tomcat的类加载太多,应该和数据库连接之间没有太大的关系。
    
3、出现这个原因 楼主可以用 jconsole 或者jvisualvm 来查看到底是哪儿出问题了。

tomcat7和Eclipse vm都改了也不行,期初tomcat下放了几个项目,大概一共有一百多个jar,很容易发生PermGen,后来只留一个项目还是发生,正如21#所说,我发现我只要clean up项目就发现PermGen,修改文件,一会就会发生,Eclipse是自动编译、部署,应该就是这个原因,避免频繁的热部署,而是重启服务器。

引用 22 楼 PHIILL_01 的回复:

1、如果你是在Eclipse中运行,应该修改Eclipse里面启动tomcat的参数,而不是修改在“echo “Using CATALINA_BASE: $CATALINA_BASE””上面加入以下行。这样添加只有单独启动tomcat的时候有作用。
 Eclipse VM  arg eg:
-Dcatalina.base=”E:\TMS\apache-tomcat-7.0.52″ -Dcatalina.home=”E:\TMS\apache-tomcat-7.0.52″ -Dwtp.deploy=”E:\TMS\apache-tomcat-7.0.52\webapps” -Djava.endorsed.dirs=”E:\TMS\apache-tomcat-7.0.52\endorsed” -XX:PermSize=64m -XX:MaxPermSize=256m

2、OutOfMemoryError: PermGen space :出现这个的原因是 tomcat的类加载太多,应该和数据库连接之间没有太大的关系。
    
3、出现这个原因 楼主可以用 jconsole 或者jvisualvm 来查看到底是哪儿出问题了。

jvisualvm分析的结果,下面是tomcat和Eclipse PermGen space的情况,现在就一个项目,那么这个PermGen占用内存情况是否正常?

接上面:


如果你的LIB全在项目下的话,把项目下的LIB移到TOMCAT的LIB下就可以了。

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明OutOfMemoryError: PermGen space的问题