
2014-7-17
一、问题描述
Tomcat7下Webapp下同时放多个程序,启动的时候报java.lang.OutOfMemoryError: PermGen space错误。
排查:放置单个程序,启动Tomcat看看是否成功,如果单个能够成功,则说明程序没有问题,如果单个不能成功,先找出原因,保证单个程序能启动成功。
注意:对于Class文件较多的单个程序,启动Tomcat时也可能出现该错误。
二、具体原因
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。
三、解决方法
绿色版的Tomcat(该方法没试过)
在tomcat_home/bin目录下找到catalina.bat,用文本编辑器打开,加上下面一行:
set JAVA_OPTS= -Xms1024M -Xmx1024M -XX:PermSize=256M -XX:MaxNewSize=256M -XX:MaxPermSize=256M
解释一下各个参数:
-Xms1024M:初始化堆内存大小(注意,不加M的话单位是KB)
-Xmx1029M:最大堆内存大小
-XX:PermSize=256M:初始化类加载内存池大小
-XX:MaxPermSize=256M:最大类加载内存池大小
-XX:MaxNewSize=256M:这个还不清楚哈,有知道的说声
还有一个-server参数,是指启动jvm时以服务器方式启动,比客户端启动慢,但性能较好,大家可以自己选择。
安装版的Tomcat(已经试过,能正常启动)
如果tomcat是注册为windows服务并且是以服务方式启动的,那么上面的方法就无效了,因为这时tomcat启动是读取注册表的参数,而不是读取批处理文件的参数,这时我们有两种方法来设置jvm参数。
⏹第一种:使用Tomcat7w.exe设置。(我用的就是这个方法,成功了)
第一步:在Tomcat安装目录下bin\文件夹下找到Tomcat7w.exe,双击打开,设置如下图:
Initial memory pool就是初始化堆内存大小
Maximun memory pool是最大堆内存大小
第二步:在Java Options中已有内容下边加上以下内容(设置Perm Gen池的大小就要在Java Option里面加参数了)。
-XX:PermSize=256M
-XX:MaxPermSize=256M
-XX:ReservedCodeCacheSize=48M
-Duser.timezone=GMT+08
第三步:点击应用,确定,启动Tomcat即可。
⏹第二种:修改注册表。(没试过)
打开注册表->HKEY_LOCAL_MACHINE\\SOFTWARE\\Apache Software Foundation\\Procrun 2.0\\Tomcat6\\Parameters\\Java(路径可能有一点点差别)
修改Option的值,把刚才上面那些参数加进去就OK了。(别忘了先备份一下注册表)
⏹第三种解决方法(没试过)
建议:将相同的第三方jar文件移置到tomcat/shared/lib目录下,这样可以达到减少jar 文档重复占用内存的目的。
⏹参考:
http://blog.163.com/linyunpeng1029@126/blog/static/1656206362010111555820706/
http://www.cnblogs.com/xwdreamer/archive/2011/11/21/2296930.html
