使用Jetty时出现java.lang.OutOfMemoryError: PermGen空间错误

6

我目前遇到了一个 java.lang.OutOfMemoryError: PermGen space 的问题。我正在使用 Jetty 和 Linux Ubuntu。我尝试阅读并尝试以前类似问题提供的不同解决方案,但我没有任何成功。一个类似的问题是

处理“java.lang.OutOfMemoryError:PermGen空间”错误

但这些解决方案似乎是使用 Tomcat 而不是 Jetty。如果我重新部署我的服务几次,我会持续收到内存不足的错误。例如,为了测试这个,我进入我的 webapps 文件夹并运行 touch *.xml 来更新时间戳,然后重新运行 jetty,我就会得到内存不足的错误。在我的 jetty 文件夹中(包括 bin、doc、etc、lib、logs、modules、start.jar),我正在运行

java -jar ../start.jar

但这样做会导致错误。我尝试了其他示例中的方法,例如:
java -jar ../start.jar JAVA_OPTS="-Xms256m -Xmx512m -XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled"

或者

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled

或者
-XX:MaxPermSize=128m

当我在Firefox中导航到localhost:8080并刷新页面时,在终端中我不断收到错误提示。

java.lang.OutOfMemoryError: PermGen space
5个回答

4

除了将MaxPermSize增加到更高的值(例如1024m)外,您无法做任何事情:

-XX:MaxPermSize=1024m

这是一个常见的问题,在Jetty文档-预防内存泄漏章节中也有解释:

Permgen问题

Jetty中的JSP引擎是Jasper。它最初是在Apache Tomcat项目下开发的,但随着时间的推移,它已经被许多不同的项目分支了出来。所有Jetty版本到6都只使用基于Apache的Jasper,Jetty 6仅使用Apache Jasper进行JSP2.0。随着JSP 2.1的出现,Jetty 6转而使用来自Sun Glassfish项目的Jasper,现在是参考实现。

所有Jasper的分支都存在一个问题,即通过使用jsp标记文件可能会导致permgen空间不足。这是由于jsp实现的类加载架构所导致的。每个jsp文件实际上都会被编译并在其自己的类加载器中加载,以便进行热替换。每个包含对标记文件的引用的jsp将在必要时编译该标记文件,然后使用它自己的类加载器加载它。如果您有许多jsp引用相同的标记文件,则标记的类将被加载多次进入permgen空间,每个jsp一次。相关的Glassfish bug报告是bug#3963,等效的Apache Tomcat bug报告是bug#43878。 Apache Tomcat项目已经关闭了此错误报告,并标记为WON'T FIX,但Glassfish团队仍然保留着此错误报告,并计划修复它。当修复程序可用时,Jetty项目将采用并纳入我们的发行计划


2
希望您能够通过使用我的ClassLoader Leak Prevention library轻松解决这些问题。在您自己的代码和第三方库中,都可能会出现导致此类内存泄漏的不同错误。有关该问题的更多信息、如何跟踪它以及已知的罪犯,可以在我的博客系列中找到。特别注意Jetty本身可能会导致某些版本的这种泄漏此错误

0

您可以在Jetty主目录中的start.ini文件中添加这些参数。如果仅此不起作用,您可以尝试设置更高的MaxPermSize,例如1024m。


0

在Jetty 9.2+中

在您的${jetty.base}目录中,添加jvm模块和默认配置

[user]$ cd mybase
[mybase]$ java -jar /path/to/jetty-distribution/start.jar --add-to-start=jvm
INFO: jvm             initialised in ${jetty.base}/start.ini (appended)
[mybase]$ 

现在去编辑你的${jetty.base}/start.ini文件并配置属性,取消注释你想要的内容(不要忘记取消注释--exec),当Jetty启动时使用这些属性。

例如:

# --------------------------------------- 
# Module: jvm
--module=jvm
## JVM Configuration
## If JVM args are include in an ini file then --exec is needed
## to start a new JVM from start.jar with the extra args.
##
## If you wish to avoid an extra JVM running, place JVM args
## on the normal command line and do not use --exec
--exec
-Xmx1024m
-Xmn512m
-XX:MaxPermSize=128m
# -XX:+UseConcMarkSweepGC
# -XX:ParallelCMSThreads=2
# -XX:+CMSClassUnloadingEnabled
# -XX:+UseCMSCompactAtFullCollection
# -XX:CMSInitiatingOccupancyFraction=80
# -verbose:gc
# -XX:+PrintGCDateStamps
# -XX:+PrintGCTimeStamps
# -XX:+PrintGCDetails
# -XX:+PrintTenuringDistribution
# -XX:+PrintCommandLineFlags
# -XX:+DisableExplicitGC
# -Dorg.apache.jasper.compiler.disablejsr199=true

0

这是一个比较老的问题,但是这个解决方案可以解决我的问题:

contextHandler.setInitParameter("org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false");


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