1

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

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)

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

4

2 回答 2

2

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

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

于 2012-03-16T20:47:27.693 回答
0

不久,我不得不在我的 Web 应用程序中使用 servlet sepc 3.0 处理带有 Mojarra 2.2.12 的 Apacht Tomcat 8.0.26 上名为“ Mojarra-WebResourceMonitor-1-thread-1 ”的泄漏线程。

根本原因是 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>
于 2015-09-30T11:04:47.577 回答