【问题标题】:PermGen Space error on hot deploys on Tomcat在 Tomcat 上热部署时出现 PermGen Space 错误
【发布时间】:2012-04-02 09:45:25
【问题描述】:

每次重新部署后,我都会在日志中看到以下消息。

INFO: Reloading Context with name [/x1Application] has started
SEVERE: The web application [/x1Application] appears to have started a thread named [Mojarra-WebResourceMonitor-1-thread-1] but has failed to stop it. This is very likely to create a memory leak.
SEVERE: The web application [/x1Application] appears to have started a thread named [Hector.me.prettyprint.cassandra.connection.CassandraHostRetryService-1] but has failed to stop it. This is very likely to create a memory leak.

最终在 1-2 次热部署后,服务器停止响应,我收到 PermGen 空间错误

17 Mar, 2012 1:40:01 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [jsp] in context with path [] threw exception [The HTTP Monitor server side component intercepted and rethrew an error while processing a JSP or servlet. Please see the stack trace under the root cause message below to identify the problem.] with root cause
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 java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:382)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:333)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:182)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
17 Mar, 2012 1:40:12 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [jsp] in context with path [] threw exception [The HTTP Monitor server side component intercepted and rethrew an error while processing a JSP or servlet. Please see the stack trace under the root cause message below to identify the problem.] with root cause
java.lang.OutOfMemoryError: PermGen space
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:382)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:333)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:182)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

如何获得更多关于错误来源的信息?

【问题讨论】:

标签: java tomcat out-of-memory hector permgen


【解决方案1】:

我会向赫克托人报告。这是他们的错误,他们的代码在 webapp 关闭时没有正确关闭正在运行的线程。同时,您可以考虑选择更好的开发服务器(最喜欢的是Glassfish;它会在亚秒内进行热部署)或安装JRebel 以将Tomcat 转换为真正的热部署器而不是热启动器。

关于Tomcat的内存泄漏保护的背景资料,请阅读以下wiki:

【讨论】:

  • 感谢 BalusC。我刚刚注意到还有一条名为Mojarra-WebResourceMonitor-1-thread-1] 的线程的消息。所以这也可能是受害者..!
  • 这很奇怪。这个应该在ConfigureListener#contextDestroyed() 中关闭。也许它没有在所有 ServletContextListeners 上调用 contextDestroyed() 真的是 Tomcat 自己的错?
  • 错误发生在“JSP”servlet 中,而第一条消息是从“JSF”发送的……我猜你在这里混合了一些技术。看起来像一个错误的 *.jsp 文件。
  • @Stefan:这只是巧合。在整个 webapp 的代码中,OutOfMemoryError 会在何时何地发生,这绝对是不可预测的。当堆已满且 GC 未能清扫它时,它会随时发生。
【解决方案2】:

很快我不得不处理一个名为“Mojarra-WebResourceMonitor-1-thread-1”的泄漏线程 Apacht Tomcat 8.0.26 与 莫哈拉 2.2.12 在我的网络应用中使用 servlet sepc 3.0。

根本原因是 com.sun.faces.config.ConfigureListener两个实例已添加到 ServletContext。

第一个实例 (A) 被 Tomcat 的容器 SCI 添加 org.apache.jasper.servlet.JasperInitializer.onStartup(...) 因为它是在 javax.faces-2.2.12.jar!/META-INF/jsf_core.tld 中配置的

第二个实例 (B) 由
com.sun.faces.config.FacesInitializer.onStartup(...)添加

解决方法是通过编辑我的 Web 应用程序 context.xml 并将 containerSciFilter 属性添加到上下文元素来阻止 JapserInitializer 调用:

<Context containerSciFilter="org.apache.jasper.servlet.JasperInitializer|org.apache.tomcat.websocket.server.WsSci">

我的网络应用不需要这两个 SCI。因此,如果您依赖 JSP 和 JSF,这种解决方法将无济于事。


这就是这里发生的错误:

在Servlet初始化时,tomcat调用

  • A.contextInitialized(...)
    • 初始化 JSF
    • 启动线程池
  • B.contextInitialized(...)
    • 由于 JSF 正在运行...无事可做

关机时,tomcal 调用:

  • B.contextDestroyed(...)
    • 关闭 JSF
    • 不知道任何线程池,因为我还没有启动。
  • A.contextDestroyed(...)
    • 由于 JSF 停止,无事可做。

因此 As 的 threadPool 保持启动并运行,防止 WebAppClassloader 上的 GC。

但这是谁的错呢?

  1. Tomcat 是否未能拒绝同一类的多个侦听器?
  2. 在没有 JSF 启动和运行时,JSF Mojarra 是否因为线程池不存在而无法停止线程池?
  3. 监听器被声明两次是不是错了:
    • 通过 SCI 编程
    • 在核心 TLD taglib 中声明。

编辑:完全跳过 JasperInitializer 对我来说是有问题的。我必须将它从 containerSciFilter 中删除并将 javax.faces-*.jar 添加到 Tomcat tldSkip 过滤器,如下所示:

<JarScanner>
  <JarScanFilter defaultPluggabilityScan="false"
    pluggabilityScan="${tomcat.util.scan.StandardJarScanFilter.jarsToScan}, javax.faces-*.jar"
    tldSkip="${tomcat.util.scan.StandardJarScanFilter.jarsToSkip}, , javax.faces-*.jar" />
</JarScanner>

【讨论】:

    猜你喜欢
    • 2013-03-09
    • 1970-01-01
    • 2016-03-26
    • 2011-12-14
    • 1970-01-01
    • 2015-05-27
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多