将项目转换为Maven后出现java.lang.OutOfMemoryError: PermGen空间错误

3
这个主题有几个问题,我看了所有答案,但仍然存在相同的问题。我正在尝试对以前没有使用Spring的现有项目实施Spring Security。我成功地将其转换为Maven项目并添加了一个登录表单,没有任何问题。我继续进行更多更改,然后离开一天,第二天回来后,Tomcat开始抛出这个错误。我试图回滚我所做的更改,但没有任何改变,直到我禁用了项目的Maven特性。我一旦这样做,错误就消失了,一旦我配置成Maven项目,错误就会返回。
我尝试了其他stackoverflow答案中建议的以下事项:
  • 在环境变量中添加_JAVA_OPTIONS -Xmx1024m用户变量
  • 在环境变量中添加MAVEN_OPTS-Xmx1024m用户变量
  • 在eclipse.ini中在-vmargs之后添加-XX:MaxPermSize = 128M和-XX:PermSize = 128M
  • 将Java_OPTS设置为-XX:+ CMSClassUnloadingEnabled-XX:+CMSPermGenSweepingEnabled
  • 在我的POM中添加-Xmx512m
  • 在我的Tomcat启动配置中添加-XX:MaxPermSize = 512m和-XX:PermSize = 512m
最初Perm Generation为99%,但是在将-XX:PermSize = 128M添加到eclipse.ini之后,它降至更低的百分比,但此问题仍然存在。
提前感谢!在这一点上,任何建议都将有所帮助。
我要么得到两个错误中的一个,它们非常相似,只是堆栈跟踪不同。
java.lang.OutOfMemoryError: PermGen space
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
    at java.lang.Throwable.getStackTraceElement(Native Method)
    at java.lang.Throwable.getOurStackTrace(Throwable.java:591)
    at java.lang.Throwable.printStackTrace(Throwable.java:462)
    at java.lang.Throwable.printStackTrace(Throwable.java:451)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:450)

java.lang.OutOfMemoryError: PermGen space
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(Unknown Source)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2818)
    at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1148)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1643)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1521)
    at org.apache.catalina.startup.ContextConfig.checkHandlesTypes(ContextConfig.java:1956)
    at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:1919)
    at org.apache.catalina.startup.ContextConfig.processAnnotationsJar(ContextConfig.java:1806)
    at org.apache.catalina.startup.ContextConfig.processAnnotationsUrl(ContextConfig.java:1765)
    at org.apache.catalina.startup.ContextConfig.processAnnotations(ContextConfig.java:1751)
    at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1255)
    at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:882)
    at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:317)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:89)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5081)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1033)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:774)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:1033)
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:291)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:443)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:727)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:620)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

更新: 正如评论中所建议的,这似乎完全显示了问题所在。Perm Gen被完全填满。这和jmap(另一张图片)显示的有什么区别?其中一个说是16MB且已满,另一个说是128MB且还有空间。我该如何增加此图片中的Perm Gen? enter image description here enter image description here

2
你如何启动Tomcat? - jmj
我会打开 jvisualvm 并获取更多关于内存使用情况的信息。 - ug_
我通过Eclipse启动Tomcat,之前没有遇到任何问题。 @ug_ 看起来visualvm中的Perm Gen大小与jmap告诉我的不同。无论我之前做了什么,似乎都增加了jmap数字,但未增加visual vm显示的数字。有什么想法吗? - farnett
2
你的屏幕截图的perm gem指向的是jvisualvm进程,而不是你的maven进程。你能选择pid 5856并检查perm gem吗? - hutingung
谢谢,我已经将这两张图片添加到帖子中。正如你所看到的,它显示我已经增加了Perm Gen大小,并且有空闲空间。然而,错误仍然存在。Maven是否有单独的Perm Gen空间? - farnett
MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=?? 有什么帮助吗? - rogerdpack
1个回答

1
我相信您正在使用m2e插件。如果您正在使用m2e执行maven进程,它将启动一个单独的jvm。您需要为该进程配置VM参数。请参考下面的截图。您可以先尝试一个简单的maven项目,然后再应用到您的项目中。
示例pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>foo</groupId>
    <artifactId>bar</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  1. 配置maven目标。确保选择项目工作区并正确设置maven目标。如果使用tomcat7插件,则应使用tomcat7:run maven goal
  2. 配置VM参数。例如:-Xmx1024m -Xms1024m -XX:MaxPermSize=512m -XX:PermSize=256m enter image description here
  3. 检查您使用JVisualVM设置的JVM参数。选择进程并从概述选项卡中获取它。如下所示的示例截图。 enter image description here

我正在使用m2e。我不知道这是否相关,但当我按照您建议的操作并运行时,它会给我一个错误,说此构建未指定任何目标。通常我不会明确告诉maven构建我的项目。另一次我这样做时遇到了相同的错误,但像往常一样启动了tomcat,它就可以工作了。这次我输入了那些参数,但是构建失败了,tomcat仍然抛出相同的错误。 - farnett
@farnett,未指定目标的原因是您没有正确设置Maven目标。我添加了示例pom.xml并在答案中提供了更详细的步骤。试试看吧。 - hutingung
抱歉耽搁了。我按照你说的添加了目标并运行了我的项目,但出现了非常奇怪的情况。它开始在我指定的URL上运行我不认识的代码(这是一个在我的项目中不存在的Spring安全示例)。我能想到唯一可能导致这种情况的原因是Maven依赖项。我找到了一个未使用的依赖项并将其删除,现在程序正在运行。但我不认为我已经解决了问题,只是推迟了它。也许删除那个依赖项释放了一些PermGen空间? - farnett
是的,较少的依赖意味着加载的类较少。这将减少perm gem的使用。但是您是否检查了正在运行的tomcat是否已配置了java opts? - hutingung
很遗憾,我无法确定是什么解决了问题,但最有可能是多种因素的组合,不过现在Tomcat似乎已经识别了新的PermGen空间。感谢所有的帮助,我非常感激! - farnett

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