如何处理Tomcat的PermGen空间问题

27

背景:我有一个使用 JSP 的 Web 项目。IDE 是 Eclipse。 Tomcat 的配置是:当资源更改时自动发布,发布间隔为“1 秒钟”。

在 classes 文件夹中有一个属性文件,用于保存一些设置。它也可以被 servlet 动态修改。修改操作由 JSP 中的保存按钮触发。

问题:经过几次保存操作后,Tomcat 出现了 java.lang.OutOfMemoryError: PermGen space 错误。

日志信息

java.lang.OutOfMemoryError: PermGen space
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1815)
    at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:872)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1325)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1204)
    at org.apache.catalina.startup.WebAnnotationSet.loadApplicationServletAnnotations(WebAnnotationSet.java:108)
    at org.apache.catalina.startup.WebAnnotationSet.loadApplicationAnnotations(WebAnnotationSet.java:58)
    at org.apache.catalina.startup.ContextConfig.applicationAnnotationsConfig(ContextConfig.java:297)
    at org.apache.catalina.startup.ContextConfig.start(ContextConfig.java:1064)
    at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:261)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:120)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4238)
    at org.apache.catalina.core.StandardContext.reload(StandardContext.java:3083)
    at org.apache.catalina.loader.WebappLoader.backgroundProcess(WebappLoader.java:404)
    at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1279)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1571)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1580)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1580)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1560)
    at java.lang.Thread.run(Thread.java:662)

2
请阅读下面的文章,完整解释了如何配置Tomcat以增加PermGen [Tomcat PermGen Space](http://www.mkyong.com/tomcat/tomcat-javalangoutofmemoryerror-permgen-space/) - Phani
潜在的重复问题。 https://dev59.com/v3VD5IYBdhLWcg3wGXlI - Phani
3
每当人们反复重新部署Web应用程序而不重启Tomcat时,我会在Tomcat中遇到此错误。由于与类加载过程相关的泄漏,每次重新部署后PermGen空间都会变得更加充满。增加PermGen大小可以延迟其耗尽内存的时间点,但实际上,您需要确保在重新部署Web应用程序时重新启动Tomcat。 - Jon
可能是PermGen space Error in tomcat的重复问题。 - Steve Chambers
7个回答

34

Tomcat确实需要大量的permgen。512m并不是一个不合理的上限。然而,它只会延迟热部署泄漏。每次热部署Permgen会增长约25mb,在Eclipse中,这可能是每次保存Java文件时。如果你像我一样有Ctrl+S抽搐,512m会很快消失。

解决方案:允许Java将类定义从内存中清除,即垃圾回收字节码。将这些方法与提高的permgen大小一起添加:

-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC

@dldnh你能否提及应该添加到setenv.sh文件的完整行? - Alex
为什么默认情况下没有启用它? - jonasespelita

15

您可以设置名为"JAVA_OPTS"的环境变量,并将其值设置为以下内容:-Xms256m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m


它看起来可以避免问题,但不是好的解决方案。我怀疑频繁地在属性文件中保存数据是否是一种错误的设计,如果是不好的,应该怎么做? - SKing7
2
实际上是 -Xms256m -Xmx1024m。Xms 是初始大小,而 Xmx 是最大堆大小。 - Marcio Aguiar

6

对于Eclipse

  1. 进入服务器属性
  2. 进入平台
  3. 现在在VM参数中写下以下内容: -Xms256m -Xmx256m -XX:PermSize=256m -XX:MaxPermSize=512m

对于Netbeans

  1. 进入Netbeans文件夹/etc/
  2. 用任何编辑器打开netbeans.config文件
  3. 将此行编辑为:

netbeans_default_options="-J-client -J-Xss256m -J-Xms256m -J-XX:PermSize=256m -XX:MaxPermSize=512m -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dsun.java2d.dpiaware=true -J-Dsun.zip.disableMemoryMapping=true"

这就是全部内容了。


5
设置如下:
-Xms128m -Xmx1024m -XX:PermSize=64m -XX:MaxPermSize=256m

enter image description here


3
只需从Apache Tomcat界面进行配置即可:
  1. 启动C:\ Program Files \ Apache Software Foundation \ Tomcat 8.5 \ bin \ Tomcat8w.exe(或者您可以在Windows开始菜单中搜索“配置Tomcat”);
  2. 进入Java选项卡;
  3. 在输入字段中设置所需的空间: enter image description here
请注意,保留HTML标记。

1

仅针对Windows系统,如果有人依然困惑,请参考以下步骤:

  1. 打开catalina.bat文件(位于Apache Tomcat安装路径/bin)
  2. 在文件的最开始设置JAVA_OPTS如下(在文件中的第一次使用之前):--

    set JAVA_OPTS=-Dfile.encoding=UTF-8 -Xms128m -Xmx1024m -XX:PermSize=64m -XX:MaxPermSize=256m

  3. 重新启动Tomcat即可。

你可以在这里找到详细的解释。


0

Tomcat服务器运行不同的JAVA,而Eclipse运行在不同的JAVA上。

因此,在eclipse.ini中添加-XX:MaxPermSize=512m可以帮助解决这个问题。按照以下步骤将其添加到Tomcat服务器中:

  • 双击Eclipse中的服务器

  • 打开启动配置

  • 在参数选项卡中的VM参数中添加“-XX:MaxPermSize=512m”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接