一、問題環境
最近在部署一個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參數。截圖如下(沒有嘗試):
三、最終結果
待續。