在tomcat的配置文件server.xml中:
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="localhost_access_log." suffix=".txt"/> <Context docBase="F:\LAMP\Tomcat7.0\me-webapps\SZU_MC" path="/SZU_MC" reloadable="false" source="org.eclipse.jst.jee.server:SZU_MC"/> </Host>
2、上面的
reloadable="false"
的作用为:
reloadable:如果这个属性设为true,tomcat服务器在运行状态下会监视在WEB-INF/classes和WEB-INF/lib目录下class文件的改动,如果监测到有class文件被更新的,服务器会自动重新加载Web应用。
在开发阶段将reloadable属性设为true,有助于调试servlet和其它的class文件,但这样用加重服务器运行负荷,建议在Web应用的发存阶段将reloadable设为false。
==============================================================================================================
1.问题描述
今天更新了代码到svn上,然后更新代码,重启tomcat服务器,发现服务器无法正常运作。刚开始可以启动,可以访问,但是过了一会就无法访问了。于是tomcat目录下定位到log文件夹,并查看了日志,由于我没有认真从头研究日志,只翻到最后,发现了这个错误:java.lang.OutOfMemoryError: PermGen space。
2.解决历程
然后一番搜索,摘抄部分内容来自http://blog.csdn.net/fengyie007/article/details/1780375;
=========================================================
PermGen
space的全称是Permanent Generation space,是指内存的永久保存区域OutOfMemoryError:
PermGen
space从表面上看就是内存益出,解决方法也一定是加大内存。说说为什么会内存益出:这一部分用于存放Class和Meta的信息,Class在被
Load的时候被放入PermGen space区域,它和和存放Instance的Heap区域不同,GC(Garbage
Collection)不会在主程序运行期对PermGen
space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen
space错误。这种错误常见在web服务器对JSP进行pre compile的时候。改正方法:-Xms256m -Xmx256m
-XX:MaxNewSize=256m -XX:MaxPermSize=256m
2、在tomcat中redeploy时出现outofmemory的错误. 可以有以下几个方面的原因:
1,使用了proxool,因为proxool内部包含了一个老版本的cglib.
2, log4j,最好不用,只用common-logging
3, 老版本的cglib,快点更新到最新版。
4,更新到最新的hibernate3.2 3。
=========================================================
原来是要设置-XX:PermSize的大小,而且说是libs太多了,导致内存不够。设置之后,发现仍然存在这个问题。
一番各种纠结,比如自己在eclipse使用jetty都能完美运行。。。后来没办法决定仔细研读错误日志。然后发现了这一句:
org.apache.catalina.startup.Catalina.start Server startup in 12717 ms
20-Jan-2015 23:54:48.452 INFO [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.core.StandardContext.reload Reloading Context with name [/eduplatform] has started
上面从时间上可以看到tomcat下面的项目已经加载完毕了,但是之后就reload了,然后我就发现了接下来的几句
20-Jan-2015 23:54:48.465 WARNING [ContainerBackgroundProcessor[StandardEngine[Catalina]]] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesJdbc The web application [eduplatform] 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.
日志上说我的项目注册了jdbc的驱动,但是项目关闭的时候,并没有取消驱动的注册。当时我就郁闷了,我的项目被关闭过?不是启动的好好的吗,接着后面的几句都是这样子提示,这说明我的项目被启动了,又关闭了,若干次,然后就报了一个内存溢出的异常了。
后来思考我今天提交了什么东西?之前的服务器代码明明是没问题的,为什么会出现这个情况呢?原来此次的更新代码上,我在项目的初始化init()函数里面,动态修改了jpa的persistence.xml文件,这个文件是放在编译好的源码的classes目录下的\WebRoot\WEB-INF\classes\META-INF文件夹里面。
下面说说我是怎么发现reloaded导致的问题的。
上面有句我抓住了重点词。reload Reloading Context。通过搜索tomcat
reload,顺蔓摸瓜,找到了这个特性,加上以前也有耳闻热部署技术。其实上面的博客也有这个词语。redeploy,但是还是没有能够解决我的问题。
然后了解到了reloaded的特性,会检测项目的文件是否被修改过,然后就开始重新加载项目,做到所谓的热部署。。。。
显然这样子的话,我的项目便陷入了一个死循环,那就是init初始化的时候,动态修改了配置文件,而tomcat又检测配置文件经过了修改。于是重启我的项目。。。。悲剧就这样产生了,最后修改tomcat的项目配置文件,修改成false就可以了。项目正常运行。