一、问题环境
最近在部署一个web项目时,遇见前台一个发送请求后台tomcat服务器什么都不响应的问题,看了下tomcat的控制台,发现一直在打印以下异常:
1 Exception in thread "http-apr-8080-exec-2" java.lang.OutOfMemoryError: PermGen space

Exception in thread "http-apr-8080-exec-10" java.lang.OutOfMemoryError: PermGen space at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631) at java.lang.ClassLoader.defineClass(ClassLoader.java:615) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141) at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2957) at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1210) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1690) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571) at freemarker.template.Template.<init>(Template.java:166) at freemarker.cache.TemplateCache.loadTemplate(TemplateCache.java:447) at freemarker.cache.TemplateCache.getTemplate(TemplateCache.java:360) at freemarker.cache.TemplateCache.getTemplate(TemplateCache.java:235) at freemarker.template.Configuration.getTemplate(Configuration.java:578) at freemarker.template.Configuration.getTemplate(Configuration.java:543) at org.apache.struts2.dispatcher.Dispatcher.sendError(Dispatcher.java:859) at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:586) at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77) at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2441) at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2430)
上网搜索了下问题原因,网上说PermGen space区域的内存溢出,一般都是因为Tomcat中的部署项目过多导致,tomcat启动时需要加载每个项目的第三方jar,当第三方jar包过多,超过jvm的默认内存(4M)时,就会抛这个异常。我想了下,这个项目我以前在其他机器上也部署过没有内存溢出的问题,现在由于新部署的机器是64位的jre,导致程序有很多修改,尤其是底层和硬件通信模块变动较大,且添加了第三方jar包,不知是否是因为这个原因导致的内存溢出。先试下增大tomcat的jvm内存,试试能否解决该问题。网上还有一人也是遇见这个异常,但是他的原因是因为jasper配置sql的有问题(源网址由于博客园判定非法故无法贴出),我虽然要用到过jasper但是一直没改过应该不是这个原因。
二、问题解决
1、按照网上的方法修改tomcat的tomcat/bin/catalina.bat(linux为catalina.sh),在setlocal(第一行)添加如下JAVA_OPTS初始配置(512m后面含有一个空格):
1 setlocal 2 JAVA_OPTS="-server -XX:PermSize=256M -XX:MaxPermSize=512m "
结果修改内存成功了,如果语法有错误,可能会导致tomcat起不来,建议先备份整个tomcat文件夹。但问题原因还是没有解决,而且仔细尝试发现只在调用底层模块时才会出现内存溢出,在未调用底层模块之前是可以正常处理数据库查询请求的。
2、还有一种tomcat是简化版的,直接运行tomcat.exe就可以启动,没有catalina文件,可以运行tomcatw.exe在java界面配置jvm参数。截图如下(没有尝试):
三、最终结果
待续。